我已经查看了以前的帖子,他们没有帮助我找到我的问题...为了使它保持简短线(是的,我确实意识到有很多这样的帖子)。但是,当我通过CMD运行程序时,它给了我这个错误:
Program received signal SIGSEGV, Segmentation fault.
__GI___libc_realloc (oldmem=0x10011, bytes=1) at malloc.c:2999
2999 malloc.c: No such file or directory.
我 Pretty 确保我正确地写出了Malloc/Realloc线条。我尝试找到类似的帖子,但是提供的解决方案没有帮助。如果您有任何帖子建议,也许我错过了,请告诉我。无论如何,这是我的功能:
char* read_single_line(FILE* fp){
char* line = NULL;
int num_chars = 0;
char c;
fscanf(fp, "%c", &c);
while(!feof(fp)) {
num_chars++;
line = (char*) realloc(line, num_chars * sizeof(char));
line[num_chars -1] = c;
if (c == 'n') {
break;
}
fscanf(fp, "%c", &c);
}
if(line != NULL) {
line = realloc(line, (num_chars+1) * sizeof(char));
line[num_chars] = ' ';
}
return line;
}
void read_lines(FILE* fp, char*** lines, int* num_lines) {
int i = 0;
int num_lines_in_file = 0;
char line[1000];
if (fp == NULL) {
*lines = NULL;
*num_lines = 0;
} else {
(*lines) = (char**)malloc(1 * sizeof(char*));
while (read_single_line(fp) != NULL) {
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
num_lines_in_file++;
i++;
}
*lines[i] = line;
*num_lines = num_lines_in_file;
}
}
我真的很感谢任何帮助 - 我是C的初学者,所以请听我说话!
char line[1000];
:
while (read_single_line(fp) != NULL) {
:
}
*lines[i] = line;
这对我来说并不完全。您的read_single_line
函数返回实际行,但是除了检查NULL
之外,您实际上永远不会在任何地方存储。取而代之的是,您将行指针指向line
,这是一个自动划分的变量,它可能包含任何东西(并且更令人担忧,可能没有终结器字符)。
我认为您可能应该从read_single_line
存储返回值,并使用它来设置线条指针。
顺便说一句,一次扩展一个角色也可能非常低效。我建议最初分配更多字节,然后保留当前正在使用的容量和字节。然后,只有当您要超越能力超出能力时,您才会扩展,并且超过一个。在伪代码中,类似:
def getLine:
# Initial allocation with error check.
capacity = 64
inUse = 0
buffer = allocate(capacity)
if buffer == null:
return null
# Process each character made available somehow.
while ch = getNextChar:
# Expand buffer if needed, always have room for terminator.
if inUse + 1 == capacity:
capacity += 64
newBuff = realloc buffer with capacity
# Failure means we have to release old buffer.
if newBuff == null:
free buffer
return null
# Store character in buffer, we have enough room.
buffer[inUse++] = ch
# Store terminator, we'll always have room.
buffer[inUse] = ' ';
return buffer
您会注意到,以及更有效的重新分配,对上述分配进行更好的错误。
while (read_single_line(fp) != NULL) {
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
num_lines_in_file++;
i++;
}
*lines[i] = line;
在这个短片段中有更多的错误。让我们一个一个一个吧。
while (read_single_line(fp) != NULL)
您阅读了一条线,检查它是否是空指针,然后将其扔掉,而不是将其放在lines
数组中。
(*lines)[i] = (char*)realloc((*lines)[i], sizeof(char));
您正在尝试进行Realloc (*lines[i])
。首先,它不存在于i==0
之外,因为(*lines)
仅被分配给包含一个元素。其次,对于Realloc的单个线路来说,这是没有意义的,因为您(应该)从线条阅读功能中获得完美的现成线条。您想改用Realloc *lines
:
*lines = realloc (*lines, i * sizeof(char*));
现在这两行
num_lines_in_file++;
i++;
本身不是错误,但是为什么两个变量总是具有完全相同的值?此外,您希望它们(按通常的增量realloc-rassign模式)在真实行之前(您正在其他函数中使用)。
说到分配部分,没有任何东西。您现在应该插入一个:
(*lines)[i-1] = // what?
调用read_single_line时应该保存的线指针,这就是这样。从一开始:
char* cur_line;
int i = 0;
*lines = NULL;
while ((cur_line=read_single_line(fp)) != NULL)
{
++i;
*lines = realloc (*lines, i * sizeof(char*));
(*lines)[i-1] = cur_line;
}
*num_lines = i;
最后一个
*lines[i] = line;
是彻头彻尾的丑陋。
首先, lines
不是数组,它是指向单个变量的指针,因此 lines[i]
访问了绘制的灰尘。其次,您正在尝试为其分配一个局部变量的地址,该地址将在您的功能返回后立即停止存在。第三,在循环之外做什么?如果要用空指针终止行数组,请这样做:
}
*num_lines = i;
++i;
*lines = realloc (*lines, i * sizeof(char*));
(*lines)[i-1] = NULL;
但是鉴于您返回行数,这可能不是必需的。
免责声明:以上都没有测试。如果有任何错误,请修复它们!