Ошибка сегментации при сортировке массива структуры из указателя

Возможный дубликат:
Как найти ошибку в моей программе на C++?

Я получаю ошибку сегментации при сортировке структуры. Вот моя структура.

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

DATA *the_array = NULL;

Я динамически распределяю память, используя malloc и realloc. Теперь я использую пузырьковую сортировку для сортировки этой структуры. Я использую кровопролитие c/ C++ ide под Windows 7. Добавление кода, где я получаю исключение.

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);



                             }
                             }
                   }
    }

Могу ли я сделать это так

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;


                         }

               }
}

3 ответа

Решение

При копировании элементов вы, например, mallocИНГ sizeof(the_array[i].name)), который является размером указателя символа. Если имя длиннее 3 байтов, вы перезаписываете нераспределенную память при копировании в нее. Вы должны выделить strlen(the_array[i].name)+1, Аналогично для других элементов. И даже в этом случае возникает проблема, заключающаяся в том, что имя в узле X может быть короче, чем имя в узле Y, которое вы копируете в него. Вся эта стратегия обречена на провал.

Есть ли какая-то причина, по которой вы просто не меняете узлы? Или даже лучше qsort(list, N, sizeof(DATA), DataTimestampCompare);

Ваш код для обмена элементом массива вне порядка имеет несколько проблем. Ваш вопрос отмечен как C а также C++ но в C++ Вы можете просто сказать:

// Exchange the elements
if(n1 > n2)
{
    std::swap(the_array[i], the_array[j]);
}

Вам нужно только поменять местами структуры или указатели, которые они содержат. Ваш существующий код не выделяет достаточно памяти для (ненужного) копирования строк и имеет ужасные утечки памяти.

Без понимания того, как вы делаете распределение и используете массив, будет трудно ответить, но, скорее всего, вы только выделяете память для структуры и забываете об указателях на элементы. Вы также должны выделить для них память, иначе, если вы попытаетесь получить доступ к некоторым из них, вы получите ошибку сегмента.

*the_array->name Вызовет ошибку сегмента, если вы выделите память только для "the_array", например. И я предполагаю, что ваш алгоритм сортировки пытается получить доступ к некоторым атрибутам структуры.

Другие вопросы по тегам