2

嘿,我找到了一个使用 malloc 和结构数组的示例,该数组非常适合我正在尝试做的事情,但是当我将它与 qsort 结合时,我需要按结构的“数字”值排序我是运气不好。该代码可以正常运行,没有错误,但实际上并没有运行,只是崩溃了。由于我是初学者,我不知道是什么导致了问题。如果有人可以对此有所了解,那就太好了!

// Example code from "a tutorial on 'dynamic' arrays in C"
// http://fydo.net

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct DATA{
    char *name;
    int number;
} DATA;

DATA    *the_array = NULL;
int     num_elements = 0; // To keep track of the number of elements used
int     num_allocated = 0; // This is essentially how large the array is
int  compare(struct DATA *, struct DATA *);
typedef int (*compfn)(const void*, const void*);

int compare(struct DATA *elem1, struct DATA *elem2)
{
   if ( elem1->number < elem2->number)
      return -1;

   else if (elem1->number > elem2->number)
      return 1;

   else
      return 0;
}



int AddToArray (DATA item)
{
    if(num_elements == num_allocated) { // Are more refs required?

        // Feel free to change the initial number of refs and the rate at which refs are allocated.
        if (num_allocated == 0)
            num_allocated = 3; // Start off with 3 refs
        else
            num_allocated *= 2; // Double the number of refs allocated

        // Make the reallocation transactional by using a temporary variable first
        void *_tmp = realloc(the_array, (num_allocated * sizeof(DATA)));

        // If the reallocation didn't go so well, inform the user and bail out
        if (!_tmp)
        {
            fprintf(stderr, "ERROR: Couldn't realloc memory!\n");
            return(-1);
        }

        // Things are looking good so far, so let's set the
        the_array = (DATA*)_tmp;
    }

    the_array[num_elements] = item;
    num_elements++;

    return num_elements;
}

int main()
{
    // Some data that we can play with
    char *names[6] = { "Steve", "Bill", "George", "fydo", "Dave", "Jim" };
    int numbers[6] = { 42, 33, 15, 74, 5, 20 };
    int i;

    // Populate!
    for (i = 0; i < 6; i++)
    {
        DATA temp;

        temp.name = malloc((strlen(names[i]) + 1) * sizeof(char));
        strncpy(temp.name, names[i], strlen(names[i]) + 1);
        temp.number = numbers[i];

        if (AddToArray(temp) == -1) // If there was a problem adding to the array,
            return 1;               // we'll want to bail out of the program. You
                                    // can handle it however you wish.
    }

    //sort by number:
    qsort((void *) &the_array, 6, sizeof(struct DATA), (compfn)compare );

    // Regurgitate!
    for (i = 0; i < 6; i++)
    {
        printf("%s's number is %d!\n", the_array[i].name, the_array[i].number);
    }

    // Deallocate!
    for (i = 0; i < 6; i++)
    {
        free(the_array[i].name);
    }

    free(the_array);

    // All done.
    return 0;
}
4

1 回答 1

3

您以错误的方式传递数组。

它应该是

qsort(the_array, 6, sizeof(struct DATA), (compfn)compare );

qsort期望作为第一个参数的指针指向要排序的数据开始的位置,这the_array不是它的地址&the_array,因为您已经以这种方式声明了它

DATA    *the_array = NULL;

输出将是:

Dave's number is 5!
George's number is 15!
Jim's number is 20!
Bill's number is 33!
Steve's number is 42!
fydo's number is 74!

发生的情况是qsort认为数组从地址the_array开始并开始访问不允许访问的其他内存区域。

编辑

我已经用 4000 个单词尝试过了,但不能让它崩溃,这是我修改代码以从文件中读取的方法,(strdup很方便等同于malloc+ strcpy

char name[100];
while(1 == scanf("%s", name)) {
    DATA temp;
    temp.name = strdup(name);
    temp.number = rand();
    if (AddToArray(temp) == -1) 
        return 1;               
}

像这样执行:

out.exe < lorem.txt

数据正确排序、打印和释放

于 2013-04-09T18:16:03.413 回答