Reputation: 167
I have a small conceptual question about pointers. This may be embarrassing but I need to know the answer.
I was trying to read a line from a file using getline function. getline takes char ** as its first argument and that is where the line pointer is stored. Please see the pasted code below and tell me the difference between them. Notice the declaration and use of readLine pointer.
The second code gave me segmentation fault when it reached printf(). I checked the value at *readLine with gdb(before printf()) and it was correct, but when it goes to printf(), boom SIGSEGV
this code works: FILE *fp;
char *readLine;
readLine=NULL;
int s=0;
while(getline(&readLine,(size_t *)&s,fp) != -1){
printf("%s\n",readLine);
}
this code does not work: FILE *fp;
char **readLine;
*readLine=NULL;
int s=0;
while(getline(readLine,(size_t *)&s,fp) != -1){
printf("%s\n",*readLine);
}
cheers... rv
Upvotes: 0
Views: 185
Reputation: 188
Please find example bellow, it is compiled end executed on Ubuntu 18.04. If you use linux, please type "man getline", man pages are your friend.
#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);
}
Upvotes: 0
Reputation: 137770
(size_t *)&s
This will crash a 64-bit machine with 32-bit int
s. The solution to this kind of problem is to declare the type which is required (size_t s;
), not to cast anything. In x86-64, this assigns 8 bytes to a 4-byte location on the stack, which results in stack corruption. Because the overwrite happens in the called function, it could overwrite the return address, for example.
char **readLine;
*readLine=NULL;
This is also an instant crash. You are assigning a value to the target of an uninitialized pointer, changing the bytes at some unknown point in memory.
Upvotes: 2
Reputation: 81684
In the first case, the variable readLine -- the value of which is stored on the stack, in it's own special reserved area -- is a pointer-to-char. When you pass its address to getline(), you tell getline() to store the real pointer into the memory which is reserved for it. Everything works.
In the second case, readLine is a pointer-to-pointer-to-char, and again, there is space reserved for it on the stack. When you call getline(), though, you're telling getline() that the readLine variable holds the address in which the pointer-to-char should be stored. But readLine points to some random memory somewhere, not to a location which getline() should be allowed to store data. In fact, you've already started corrupting memory when you write
*readLine = NULL;
because as I said, readLine is pointing to memory you don't own. getline() just makes it worse.
Upvotes: 1