我有一个关于指针的小概念问题。这可能令人尴尬,但我需要知道答案。
我试图使用getline函数从文件中读取一行。 getline将char **作为其第一个参数,这是存储行指针的位置。请参阅下面的粘贴代码并告诉我它们之间的区别。注意readLine指针的声明和使用。
第二个代码在到达printf()时给了我分段错误。我用* gdb(在printf()之前)检查了* readLine的值并且它是正确的,但是当它转到printf()时,繁荣SIGSEGV
此代码有效: FILE * fp;
char *readLine;
readLine=NULL;
int s=0;
while(getline(&readLine,(size_t *)&s,fp) != -1){
printf("%s\n",readLine);
}
此代码不起作用: FILE * fp;
char **readLine;
*readLine=NULL;
int s=0;
while(getline(readLine,(size_t *)&s,fp) != -1){
printf("%s\n",*readLine);
}
...欢呼声 RV
答案 0 :(得分:2)
(size_t *)&s
这将使具有32位int
的64位计算机崩溃。这类问题的解决方案是声明所需的类型(size_t s;
),而不是任何东西。在x86-64中,这会将8个字节分配给堆栈上的4字节位置,从而导致堆栈损坏。因为覆盖发生在被调用函数中,所以它可能会覆盖返回地址,例如。
char **readLine;
*readLine=NULL;
这也是一次即时崩溃。您正在为未初始化指针的目标分配值,更改内存中某个未知点的字节。
答案 1 :(得分:1)
在第一种情况下,变量readLine - 其值存储在堆栈中,在它自己的特殊保留区域中 - 是指向char的指针。当你将其地址传递给getline()时,你告诉getline()将实际指针存储到为它保留的内存中。一切正常。
在第二种情况下,readLine是一个指向char的指针,同样,堆栈上还有为它保留的空间。但是,当你调用getline()时,你告诉getline()readLine变量保存了应该存储指向char的指针的地址。但readLine指向一些随机存储器,不到应该允许getline()存储数据的位置。事实上,当你写
时,你已经开始破坏内存*readLine = NULL;
因为正如我所说,readLine指向你不拥有的内存。 getline()只是让事情变得更糟。
答案 2 :(得分:0)
请在下面找到示例,它是在Ubuntu 18.04上最终编译完成的。 如果您使用linux,请输入“ man getline”,手册页是您的朋友。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
char *readLine;
FILE *fp;
size_t n = 0;
readLine=NULL;
fp = fopen("example.c", "r");
while(getline(&readLine,&n,fp) != EOF){
printf("%s\n",readLine);
}
free(readLine);
}