gpt4 book ai didi

c - 字符串数组的 malloc 时出现段错误。如何摆脱它?当分配第二个维度时,我可以发现它精确地发生

转载 作者:行者123 更新时间:2023-11-30 21:18:55 24 4
gpt4 key购买 nike

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

enum { buf = BUFSIZ };

char line[buf], **tab = NULL;

int cur_buf, count_lineMax = -1, count_line = -1,
k, l;

int main (int argc, char **argv) {

FILE *file1;
file1 = fopen(argv[1], "r");

cur_buf = buf;

/*printf("%d\n", cur_buf);*/


while(fgets(line, cur_buf, file1) != NULL) {
count_lineMax++;
/*printf("%c", line[j]);*/
}
/*printf("%d\n", count_lineMax);*/

rewind(file1);

tab = malloc(count_lineMax * sizeof(*tab));
memset(tab, 0, count_lineMax * sizeof(*tab));

/*printf("%d %ld %ld\n", count_lineMax, sizeof(*tab), count_lineMax * sizeof(*tab));*/

if(tab == NULL) {
printf("Mem_check\n");
return EXIT_FAILURE;
}

for(k=0;k<=count_lineMax;k++) {
tab[k] = malloc(cur_buf+1);
memset(tab[k], 0, cur_buf+1);

if(tab[k] == NULL) {
printf("Mem_check*\n");
return EXIT_FAILURE;
}
}

printf("%d %ld %ld\n", cur_buf, sizeof(tab), cur_buf * sizeof(*tab));

while(fgets(line, cur_buf, file1) != NULL) {

count_line++;

strcpy(tab[count_line], line);
printf("%s", tab[count_line]);
}
for(l=0;l<count_lineMax;l++) {
free(tab[l]);
}
free(tab);
return 0;
fclose(file1);
}

最佳答案

错误 1:无法验证输入(潜在的段错误)

更改此:

file1 = fopen(argv[1], "r");

对此:

if (argc != 2) {
fputs("Usage: PROGNAME FILE\n", stderr);
exit(1);
}
file1 = fopen(argv[1], "r");

错误 2:相差一索引错误(潜在的段错误)

然后,按如下方式初始化变量:

count_lineMax = 0; // -1 is incorrect
count_line = 0; // -1 is incorrect

否则,你的计数就会太小。我不知道你从哪里想到的-1但如果你有一个空文件,它应该有 0 行,对吗? (尝试给它提供一个空文件。它会崩溃。)

然后,移动count_line++到循环的底部:

while(fgets(line, cur_buf, file1) != NULL) {
strcpy(tab[count_line], line);
printf("%s", tab[count_line]);
count_line++;
}

另外,更改循环条件k<=count_lineMaxk < count_lineMax .

错误3:错误检查逻辑

下面的行是不可移植的,但它可以工作,例如在 GNU 系统上:

if (tab == NULL) {

将其更改为此,这样当在 malloc(0) 的系统上输入空文件时,它不会崩溃。返回NULL :

if (tab == NULL && count_lineMax) {

警告 4:糟糕的常量名称,#5:任意/奇怪的常量值

最后,这很糟糕:

enum { buf = BUFSIZ };

问题是你不知道什么BUFSIZ是。它可以是任何东西(我认为至少是 512)。 512不是很大。只需选择一个数字,例如

enum { BUFFER_SIZE = 1024 * 8 };

我建议不要使用名称buf以避免与局部变量混淆。使用编码风格可以帮助其他人阅读您的代码。更好的是,让变量名称更有意义:

enum { MAX_LINE_LENGTH = 1024 * 8 };
// Or if that's too verbose,
enum { MAXLINELEN = 1024 * 8 };

错误#6:输出不正确

请注意sizeof(tab)为您提供 tab 的大小变量——它是一个指针,在我的系统上是 8 个字节。您不能使用 sizeof获取 tab 中的元素数量。相反,count_lineMax保存有您要查找的号码。

建议

循环输入两次是不必要的,而且有潜在危险。恶意用户可能会在您第一次读取文件和第二次读取文件之间更改文件内容,从而导致程序崩溃。相反,我建议对 tab 使用动态大小的数组。 :只需在其中插入行,当空间不足时,增加大小。一种技术是将 tab 的大小加倍。每次它填满时。这会导致摊销渐近运行时间与文件大小保持线性关系。

关于c - 字符串数组的 malloc 时出现段错误。如何摆脱它?当分配第二个维度时,我可以发现它精确地发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7116288/

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