gpt4 book ai didi

c - free() 导致段错误

转载 作者:太空宇宙 更新时间:2023-11-04 06:00:38 25 4
gpt4 key购买 nike

在这个程序中,有一个段错误。程序可以成功打印出“loop end”,在“loop end”后出现segmentation fault,说明read_name函数没有错误。但是我无法找出我的 free_memory 函数中的任何错误。谁能帮我弄清楚?谢谢。

输入文件:

9
Clinton, Hillary R.
Bonds, Bobby S.
Bonds, Barry L.
Clinton, William I.
Clinton, Chelsea T.
Bush, Laura M.
Bush, George W.
Bush, Jenna F.
Bush, Barbara G.

程序:

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

void alloc(char ***surname, char ***first, char **mid_init, int num);
void read_names(FILE *inp, char **surname, char **first, char *mid_init, int num );
void free_memory(char **surname, char **first, char *mid_init, int num);

int main(int argc, char *argv[])
{
int num = 0;
char **surname, **first, *mid_init;
FILE *inp = fopen(argv[1], "r");
FILE *outp = fopen(argv[2], "w");
char array[79];

fscanf(inp, "%d", &num);
printf("%d\n", num);

fgets(array, 79, inp);

alloc(&surname, &first, &mid_init, num);
read_names(inp, surname, first, mid_init, num);
free_memory(surname, first, mid_init, num);

fclose(inp);
fclose(outp);

return 0;
}

void alloc(char ***surname, char ***first, char **mid_init, int num)
{
int i;

*surname = (char**)malloc(num * sizeof(char*));
*first = (char**)malloc(num * sizeof(char*));
*mid_init = (char*)malloc(num * sizeof(char));

for(i=0; i<num; i++)
{
(*surname)[i] = (char*)malloc(15*sizeof(char));
(*first)[i] = (char*)malloc(10*sizeof(char));
}
}

void read_names(FILE *inp, char **surname, char **first, char *mid_init, int num )
{
char *token, array[79];
char delim[6] = ", .\n";
int i=0;

fgets(array, 79, inp);
printf("loop begins\n");

for(i=0; i<num; i++)
{
fgets(array, 79, inp);
printf("%s", array);

token = strtok(array, delim);
strcpy( (surname[i]), token);
printf("%s ", (surname[i]));

token = strtok(NULL, delim);
strcpy( (first[i]), token);
printf("%s ", (first[i]));

token = strtok(NULL, delim);
*mid_init = token[0];
printf("%s\n", mid_init);

printf("\n\n");

}
printf("\nloop ends\n");
}

void free_memory(char **surname, char **first, char *mid_init, int num)
{
int i;

for(i=0;i<num;i++)
{
free((surname)[i]);
free((first)[i]);
}

free(surname);
free(first);
free((mid_init));
}

最佳答案

首先,您将自己限制在 14 个字符的名字和 9 个字符的姓氏中,所以这将是我检查的第一事情,您的名字不再比这个。

如果是,您可能会在复制它们时破坏内存区域。

检查这一点的一种方法是在每次设置时简单地打印 token 的长度,例如:

token = strtok(array, delim);
printf ("DEBUG: token length is %d\n", strlen (token));

请记住,腐败不一定会立即甚至永远可见。在这种情况下,最有可能发生的情况是您覆盖了内存区域中的重要内联控制信息,例如内存块大小或指向另一个内存块的指针。

但是,当您写入内存时,没有代码主动检查它,因此它可能只有在您下次尝试进行内存分配或取消分配调用时才会被发现。

损坏后你的下一个调用是你的免费调用,而且几乎可以肯定它是在哪里找到的,因为竞技场已损坏。

最重要的是,超出已分配内存末尾的写入是未定义的行为。这意味着您不应该这样做。


如果事实证明你的名字不是太长(正如你在评论中所说),你需要问问自己为什么你有一个多余的fgets(array, 79, inp); 在你的代码中。我理解为什么在 main 中需要它以便在调用 fscanf 输入行数后移动到下一行。那个很好地完成了它的工作。

但是,您在 read_names 的开头有一个另一个,它有效地丢弃了列表中的第一个名字。这会导致问题,因为当您的代码认为文件中有 X 名称时,您已经丢弃了第一个名称,这意味着只有 X - 1 剩余。您可以看出这一点,因为当您开始打印名称时,文件中的第一个名称似乎丢失了。

如果您删除 read_names 开头的 fgets,您应该会发现它没问题。

As an aside, there's a couple of other changes I'd make to the code. First you really should check all those malloc calls in case one of them fails. That's the general rule for all functions that can fail when you rely later on them not having failed.

Second, I'm not really a big fan of ever multiplying by sizeof(char) - this is guaranteed by the standard to always be 1, so multiplying by it clogs up the code and makes it less readable.

关于c - free() 导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19946208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com