【问题标题】:C: Malloc Segmentation FaultC: Malloc 分段错误
【发布时间】:2014-09-15 17:34:45
【问题描述】:

我在使用 malloc 时遇到分段错误。当我取消注释全局 COPY & LIST 变量并注释掉 malloc 和 free 调用时,程序按预期运行。

我是在误用 ​​malloc 还是 free? 如果是这样,malloc和free的正确用法是什么?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <math.h>

#define MAX_LENGTH 1000000
//int LIST[MAX_LENGTH];
//int COPY[MAX_LENGTH];

/**
 * [main description]
 * Main function reads generated data and then measures run time (in seconds) of each 
 * sorting algorithm. Data is re-shuffled to its original state for each sort.
 * @param  argc
 * @param  argv
 * @return      [returns 0 on successful run]
 * O(n^2)
 */
int main(int argc, char const *argv[])
{
    void read(int*, int*);
    void refresh(int*, int*);
    void selectionSort(long, int*);
    void bubbleSort(long, int*);
    void insertionSort(long, int*);
    time_t start, finish;
    long length = 1000;
    int *LIST = (int*) malloc(length * sizeof(int));
    int *COPY = (int*) malloc(length * sizeof(int));
    read(LIST, COPY);
    for (length = 1000; length <= MAX_LENGTH; length=length+33300) {
        //code omitted
        refresh(LIST, COPY);
        //code omitted
        refresh(LIST, COPY);
        //code omitted
        refresh(LIST, COPY);
        LIST = realloc(LIST, length * sizeof(int));
        COPY = realloc(COPY, length * sizeof(int));
    }
    free(LIST);
    free(COPY);

    return 0;
}
/**
 * [read description]
 * Reads data from stdin, and populates @LIST. 
 * Also populates @COPY, a copy of @LIST. 
 */
void read(int* LIST, int* COPY) {
    long i;
    for (i = 0; i < MAX_LENGTH; i++)
    {
        scanf("%d", &LIST[i]);
        COPY[i] = LIST[i];
    }
}

/**
 * [refresh description]
 * Copies the contents of parameter from into parameter to. 
 */
void refresh(int *LIST, int *COPY) {
    int i;
    for (i = 0; i < MAX_LENGTH; i++) {
        LIST[i] = COPY[i];
    }
}

【问题讨论】:

  • 不要在 C 中转换 malloc。如果这应该是 C++,不要使用 malloc 并避免使用 newdelete
  • 如果可用,请使用valgrind
  • 这如何与malloc 版本一起编译? refresh 函数引用了 LISTCOPY,但它们甚至没有全局定义。
  • @python 没关系。 LISTCOPY 名称不引用 refresh() 中的任何内容,无论函数是放在 main() 之前还是之后。编译器应该对此给出错误;如果不是,那么 OP 发布的代码与他遇到的问题不同。
  • @hesham8 在我发表评论时,要刷新的参数被称为fromto,但您在函数体中指的是LISTCOPY。该版本永远不会成功编译。此后,您已更新问题以解决此问题。

标签: c malloc free


【解决方案1】:

refresh() 函数让你越界了。我正在查看的版本是:

void refresh(int *LIST, int *COPY) {
    int i;
    for (i = 0; i < MAX_LENGTH; i++) {
        LIST[i] = COPY[i];
    }
}

您应该传入要复制的项目数,而不是使用MAX_LENGTH

void refresh(int n_items, int *LIST, int *COPY) {
    int i;
    for (i = 0; i < n_items; i++) {
        LIST[i] = COPY[i];
    }
}

在一个小的风格说明中,您通常应该为宏保留大写名称(在 POSIX 系统上,&lt;stdio.h&gt; 中的 FILE&lt;dirent.h&gt; 中的 DIR 是已知的例外;它们通常不是宏) .

【讨论】:

  • 你和@Dogbert 都是正确的。我设法通过更改它来解决我的问题,以便我只有一个 malloc 调用(没有重新分配)并指定为 @Dogbert 建议的:int *LIST = malloc(MAX_LENGTH * sizeof(int));。通过这样做,它也验证了刷新功能。
【解决方案2】:

您的malloc 调用中有错误。以下几行:

int *LIST=(int*) malloc(sizeof(int*) * length);
int *COPY=(int*) malloc(sizeof(int*) * length);

应该是:

int *LIST=(int*) malloc(sizeof(int) * length);
int *COPY=(int*) malloc(sizeof(int) * length);

您的realloc 电话正在做类似的事情。对于realloc 调用,我不是 100% 你的意图,但它可能应该是这样的:

LIST = (int*)realloc(LIST, length * sizeof(int));

或者,您可以只定义一些东西来表示单个元素的大小,因为您始终在整个代码中使用int 类型。

【讨论】:

  • @Nullpointer 基于read()函数,不,他不是这个打算。
  • @Nullpointer 然后LISTCOPY 的类型应该是int**,而不是int*。通常使用malloc 的模式是T* p = malloc(sizeof *T * count)
  • @jamesdlin 你的意思是T* p = malloc(sizeof T * count);
  • @cdhowie:我怀疑他在想T *p = malloc(sizeof(*p) * count);,但你是对的——当 T 是类型时,sizeof(*T) 是错误的。
  • 对,类型进入sizeof(),结果被分配给那个加一个*:例如int ** p = malloc(sizeof(int *) * count)。 @jamesdlin 犯了和 OP 一样的错误。
猜你喜欢
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
相关资源
最近更新 更多