Leftddr
Leftddr

Reputation: 79

C language Pointer related questions

Hi i'm studying pointers now. But while studying, I have a question and I want to ask

#include<stdio.h>

void store1(char **p){
    char *tmp = "hello";
    *p = tmp;
    return;
}

void store2(char *p){
    char *tmp = "hello";
    p = tmp;
    return;
}

int main(){
    char *p;
    //store1(&p, num);
    store2(p);
    printf("%s\n", p);
}

This is my questions Why does store1 function not have a segment fault and store2 function has a segment fault?

Why should we pass a variable of type char** as an argument to store a string?

If the char* type is passed as an argument, the char* tmp variable and the type match, so shouldn't it be stored in p?

Please let me know, smart brothers

Upvotes: 0

Views: 75

Answers (3)

William Pursell
William Pursell

Reputation: 212424

store2(p) does not change p, so the value of p in main remains uninitialized. The subsequent printf("%s\n", p); thus invokes undefined behavior. (Indeed, I am not a language lawyer, but I'm pretty sure invoking store2(p) when p is not initialized invokes UB.) In store1, you pass the address of p, and the call to store1 is able to modify the value of p in main so that it now points to a string literal and the subsequent printf is valid.

Here, I've re-written your code and changed some variable names to ease the discussion below:

#include<stdio.h>

void store1(char **a){ *a = "hello"; return; }
void store2(char  *b){  b = "hello"; return; }
int
main(void)
{
    char *p = NULL;   
    store2(p);  /* After store2 returns, p is still NULL */
    store1(&p); /* store1 assigns a value to p */
    printf("%s\n", p);
}

In the above, b is assigned the value NULL when store2 is called, but that value is never used. b is effectively a local variable that is assigned the address of the string literal "hello", and that variable is discarded when store2 returns. However, a is assigned the address of p, and the assignment *a = "hello" sets p to the address of the string literal "hello".

Upvotes: 3

Deduplicator
Deduplicator

Reputation: 45674

C is (outside the preprocessor, which is its own horrible beast), strictly pass-by-value.

Thus, when one says "passing a variable" in reality one nearly always means "passing the value of a variable". Yes, sloppy speaking (and/or thinking) sinks projects.
In the rare cases "passing a variable" actually means what it says, that is emulated by "passing the address of a variable". Because it is so comparatively rare and the simpler phrase has been usurped, be explicit if that's what you mean.

Naturally, changing a copy has no effect on the source at all, nor does a copy reflect changes to the source after the fact.

Now you know why p in main() is still indeterminate after the call to store2(), and why treating it as (a pointer to) a string causes Undefined Behavior.

Upvotes: 0

klutt
klutt

Reputation: 31409

Look here. I inlined the function:

int main(void)
{
    char *p;
    char *q;
    q = p;       // Pointless statment because q is overwritten                                                   
    q = "hello"; // right here                                                                                   
    puts(p);
}

Upvotes: 0

Related Questions