footloose
footloose

Reputation: 167

C Pointers question

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

Answers (3)

risbo
risbo

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

Potatoswatter
Potatoswatter

Reputation: 137770

(size_t *)&s

This will crash a 64-bit machine with 32-bit ints. 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

Ernest Friedman-Hill
Ernest Friedman-Hill

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

Related Questions