Search code examples
c++cdynamic-memory-allocation

Segmentation fault while sorting structure array made of pointer


Possible Duplicate:
How do I find a segfault in my C++ program?

I am getting the segmentation fault while sorting the structure Here is my structure

 typedef struct
    { 
    char *id; 
    char *timestamp; 
    char *name; 
    char *text;
    }DATA;

DATA *the_array = NULL;

I am dynamically allocating the memory using malloc and realloc. Now I am using bubblesort to sort this structure. I am using bloodshed c/c++ ide under Windows 7. Adding the code where I am getting the exception.

for(int i =0;i < num_elements;i++)
    {
           if(strcmp("DUP",the_array[i].id)==1)
           for(int j = i+ i; j < num_elements; j++)
                   {
                       if(strcmp("DUP",the_array[j].id)==1){
                       float n1 = strtof(the_array[i].timestamp,NULL);
                       float n2 = strtof(the_array[j].timestamp,NULL);
                       // Exchange the elements
                       if(n1 > n2)
                             {
                                  // Exchange the id
                                  temp_id = (char*)malloc(sizeof(the_array[i].id));
                                  strcpy(temp_id,the_array[i].id);
                                  strcpy(the_array[i].id,the_array[j].id);
                                  strcpy(the_array[j].id,temp_id);

                                  //Exchange the timestamps
                                  temp_timestamp = (char*)malloc(sizeof(the_array[i].timestamp));
                                  strcpy(temp_timestamp,the_array[i].timestamp);
                                  strcpy(the_array[i].timestamp,the_array[j].timestamp);
                                  strcpy(the_array[j].timestamp,temp_timestamp);

                                  //Exchange the username
                                   temp_username = (char*)malloc(sizeof(the_array[i].name));
                                  strcpy(temp_username,the_array[i].name);
                                  strcpy(the_array[i].name,the_array[j].name);
                                  strcpy(the_array[j].name,temp_username);

                                  //Exchange the text
                                  temp_text = (char*)malloc(sizeof(the_array[i].text));
                                  strcpy(temp_text,the_array[i].text);
                                  strcpy(the_array[i].text,the_array[j].text);
                                  strcpy(the_array[j].text,temp_text);



                             }
                             }
                   }
    }

Can I do it like this

for(int i =0;i < num_elements;i++)
{
       if(strcmp(dup,the_array[i].id)==1)
       for(int j = i+ i; j < num_elements; j++)
               {

                   float n1 = strtof(the_array[i].timestamp,NULL);
                   float n2 = strtof(the_array[j].timestamp,NULL);
                   // Exchange the elements
                   if(n1 < n2)
                         {
                             //Change the pointer locations
                             temp_array1 = &the_array[i];
                             temp_array2 = &the_array[j];

                             temp_array3=temp_array1;
                             temp_array1=temp_array2;
                             temp_array2=temp_array3;


                         }

               }
}

Solution

  • When copying elements, you are, for example, mallocing sizeof(the_array[i].name)), which is the size of a character pointer. If the name is longer than 3 bytes, then you are overwriting unallocated memory when you copy into it. You need to allocate strlen(the_array[i].name)+1. Similarly for other elements. And even then you have the issue that the name in node X may be shorter than the name in node Y which you are copying into it. This whole strategy is doomed to failure.

    Is there some reason you are just not swapping the nodes? Or even better doing qsort(list, N, sizeof(DATA), DataTimestampCompare);