C中的分段错误是什么原因?

时间:2014-07-18 10:18:36

标签: c

我在C中遇到分段错误,我不知道是什么原因。据我所知,当系统运行我们的内存时会发生分段故障。我检查了我的循环,他们似乎有明确的终止条件。因此,我很困惑是什么原因导致我的代码崩溃。当我检查这个错误应该发生在mygetline或readlines函数中。 是否有任何调试器可用于查找程序崩溃的原因?

#include <stdio.h>
#include <string.h>
#define MAXLINE 100
#define MAXLINENUM 10

int readlines(char *lines[]);
int mygetline(char line[]); /* getline: read a line into s, returns length */
void writelines(char *lines[], int nlines);

int main()
{

int i = 0;

char *lines[MAXLINE];
i = readlines(lines);
writelines(lines, i);

return 0;
}

int mygetline(char line[]){
    int i, c;

    for(i = 0; i < MAXLINE-1 && (c = getchar()) != '\n' && c != EOF; i++){
        line[i] = c;
    }
    line[i] = '\0';
    return i;
}

int readlines(char *lines[]){

    int i, c;
    i = 0;

    while((c = mygetline(lines++)) > 0 && i < MAXLINENUM){ //line[i]
        i++;
    }

    lines[--i] = '\0';
    return i;
}

void writelines(char *lineptr[], int nlines) {
    int i;
    for (i = 0; i < nlines; i++) 
        printf("%s\n", lineptr[i]);
}

4 个答案:

答案 0 :(得分:4)

分段错误的原因是您没有为字符串分配任何存储空间。你在这里声明了一个char*数组:

char *lines[MAXLINE];

但是你无处分配内存来保存实际的字符串。

要继续使用以这种方式分配的char*数组,您需要使用malloc为实际字符串分配内存。

lines[i] = malloc(...);

显然你需要:

  • 决定为每个字符串分配多少内存。
  • 完成后,请调用free处理内存。
  • 添加一些代码,检查您是否在任何缓冲区的末尾写字。

答案 1 :(得分:2)

您创建了一个数组char *lines[MAXLINE],它是一个指针数组。但是,您尚未初始化这些指针,因此他们指向垃圾。然后将垃圾指针传递给写入垃圾指针的mygetline,这就是问题所在。

您不仅需要为要存储的行分配内存,还需要获取mygetline可以读取的字符数。如果您为10个字符分配空间,但是用户输入20,那么您将遇到类似的问题。

答案 2 :(得分:1)

您遇到段错误的原因是您的代码将数据读入行而不为您读取的字符分配任何内存。

您的main为指向字符串的指针分配内存,但它不会初始化这些指针。您需要添加代码来设置这些指向有效内存块的指针,例如,通过malloc分配一些最大数量的字符:

while(i < MAXLINENUM) {
    lines[i] = malloc(MAXLINE);
    if (!mygetline(lines[i++])) {
        break;
    }
}

另请注意,您在MAXLINE的声明中将MAXLINENUMlines混淆。

答案 3 :(得分:1)

分段错误的原因是内存分配。 您无法分配char *lines[MAXLINE];等内存。

尝试以下代码 如果您使用的是1D阵列

char *lines;
lines=(char *)malloc(MAXLINE*sizeof(char));

如果您正在使用2D数组,请使用此代码

char **lines;
lines=(char **)malloc(MAXLINENUM*sizeof(char *));
for(i=0;i<MAXLINENUM;i++)
lines[i]=(char *)malloc(MAXLINE*sizeof(char));