尝试将标准输入读取到二维动态分配数组时出现分段错误
Segmentation fault when trying to read stdin to a 2d dynamically allocated array
我正在尝试从标准输入读取一个动态字符串数组,使用空格作为分隔符。代码如下
#include<stdio.h>
#include<stdlib.h>
char** parseInput(size_t *numElements)
{
char **lines;
int outerIndex = 0;
int innerIndex = 0;
int widths = 1;
char c=getchar();
lines =(char**) malloc((outerIndex+1)*sizeof(char*));
lines[0] = (char*) malloc(sizeof(char));
while(c!=EOF)
{
if(innerIndex==widths)//reallocate each strings length, double it
{
widths+=widths;
int i;
for(i=0;i<outerIndex+1;i++)
lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char));
}
lines[outerIndex][innerIndex]=c;
innerIndex++;
if(c==' ')//allocate memory for the next string in the array of strings
{
lines[outerIndex][innerIndex]='[=10=]';
innerIndex=0;
outerIndex++;
lines =(char**) realloc(lines,(outerIndex+1)*sizeof(char*));
lines[outerIndex] = (char*) realloc(lines[outerIndex],(widths+1)*sizeof(char));
//the above line in the debugger causes a segfault when outerIndex=19
}
c=getchar();
}
if(innerIndex!=0)//if the last character is not a space, append a space
{
if(innerIndex==widths)
{
widths+=widths;
int i;
for(i=0;i<outerIndex+1;i++)
lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char));
}
lines[outerIndex][innerIndex]=' ';
lines[outerIndex][innerIndex+1]='[=10=]';
}
*numElements=(size_t)(outerIndex+1);
return lines;
}
int main()
{
size_t num =0;
char** lines = parseInput(&num);
}
当外部数组大小增长到超过 20 个变量时,我在指示的行出现分段错误。例如,以下输入会导致段错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
但以下没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
调试错误说
Program received signal SIGSEGV, Segmentation fault.
0x0000003417e7bf4d in realloc () from /lib64/libc.so.6
这可能是由什么原因引起的?
这一行:
lines[outerIndex] = (char*) realloc(lines[outerIndex], (widths+1)*sizeof(char));
您提供了一个未初始化的指针作为 realloc
的第一个参数。您可能应该在这里使用 malloc
。
其他问题:
char c
应该是 int c
(阅读 getchar
的文档以了解原因)。
- 如果输入以 space 开头,则
lines[outerIndex][innerIndex]='[=16=]'
写入越界。
- 以
if(innerIndex==widths)
开头的代码块在您的代码中重复了两次;最好将其设为一个函数,或者重构您的代码,这样就不会出现这种重复。
- 您可以通过删除冗余转换和
sizeof(char)
的冗余乘法来简化您的 malloc/realloc 调用,它总是 1
.
- 您应该检查 malloc/realloc 是否失败并采取相应措施。
我正在尝试从标准输入读取一个动态字符串数组,使用空格作为分隔符。代码如下
#include<stdio.h>
#include<stdlib.h>
char** parseInput(size_t *numElements)
{
char **lines;
int outerIndex = 0;
int innerIndex = 0;
int widths = 1;
char c=getchar();
lines =(char**) malloc((outerIndex+1)*sizeof(char*));
lines[0] = (char*) malloc(sizeof(char));
while(c!=EOF)
{
if(innerIndex==widths)//reallocate each strings length, double it
{
widths+=widths;
int i;
for(i=0;i<outerIndex+1;i++)
lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char));
}
lines[outerIndex][innerIndex]=c;
innerIndex++;
if(c==' ')//allocate memory for the next string in the array of strings
{
lines[outerIndex][innerIndex]='[=10=]';
innerIndex=0;
outerIndex++;
lines =(char**) realloc(lines,(outerIndex+1)*sizeof(char*));
lines[outerIndex] = (char*) realloc(lines[outerIndex],(widths+1)*sizeof(char));
//the above line in the debugger causes a segfault when outerIndex=19
}
c=getchar();
}
if(innerIndex!=0)//if the last character is not a space, append a space
{
if(innerIndex==widths)
{
widths+=widths;
int i;
for(i=0;i<outerIndex+1;i++)
lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char));
}
lines[outerIndex][innerIndex]=' ';
lines[outerIndex][innerIndex+1]='[=10=]';
}
*numElements=(size_t)(outerIndex+1);
return lines;
}
int main()
{
size_t num =0;
char** lines = parseInput(&num);
}
当外部数组大小增长到超过 20 个变量时,我在指示的行出现分段错误。例如,以下输入会导致段错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
但以下没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
调试错误说
Program received signal SIGSEGV, Segmentation fault.
0x0000003417e7bf4d in realloc () from /lib64/libc.so.6
这可能是由什么原因引起的?
这一行:
lines[outerIndex] = (char*) realloc(lines[outerIndex], (widths+1)*sizeof(char));
您提供了一个未初始化的指针作为 realloc
的第一个参数。您可能应该在这里使用 malloc
。
其他问题:
char c
应该是int c
(阅读getchar
的文档以了解原因)。- 如果输入以 space 开头,则
lines[outerIndex][innerIndex]='[=16=]'
写入越界。 - 以
if(innerIndex==widths)
开头的代码块在您的代码中重复了两次;最好将其设为一个函数,或者重构您的代码,这样就不会出现这种重复。 - 您可以通过删除冗余转换和
sizeof(char)
的冗余乘法来简化您的 malloc/realloc 调用,它总是1
. - 您应该检查 malloc/realloc 是否失败并采取相应措施。