MEDOS63
MEDOS63

Reputation: 1

in c why the dereference of the s point to string value not working?

why when i use the program it return s = null

the get_string function can have update to make the program work it is : string s = malloc(sizeof(string));

but in the end of the function and after return s; i cant free(s); or before return s; i will lose the data i stored i tried to search more about dereference pointers but i got nothing.

#include <stdio.h>

typedef char* string;

string get_string(string q)
{

    string s = NULL;
    printf("%s",q);

    scanf("%s",s);

    return s;
}


int main(void)
{
    string a = get_string("name : ");

    printf("name is %s\n",a);

}

Upvotes: 0

Views: 86

Answers (2)

Steve Summit
Steve Summit

Reputation: 47952

Here are two correct uses of scanf to read a string:

char s1[10];
scanf("%9s", s1);

char *s2 = malloc(100);
scanf("%99s", s2);

Notice that in both cases — s1 and s2 — I had to explicitly say how much memory I wanted for my string. Then, when I called scanf, I included that information — 1 less than the overall string size — in the %s format, so that I could tell scanf not to read a bigger string than my string variable could hold.

Notice, by contrast, that in your get_string function, you did not allocate any memory to hold your string at all. Your variable s was a null pointer, explicitly pointing to no memory at all.

This is something that's very easy to overlook at first: Most of the time, C does not allocate memory for strings for you. Most of the time, this is your responsibility.

Now, an additional concern is that even when you do allocate memory for a string, you have to think about how long that memory will stick around, and whether anyone has to explicitly deallocate it. And there are some additional mistakes that are easy to make. In particular, suppose you took my first example (s1) to heart, and tried to fix your get_string function like this:

char *get_string(char *q)
{
    char s[100];         /* WRONG */
    printf("%s",q);
    scanf("%99s",s);
    return s;
}

Here you have given scanf a proper array to read in to, but it's local to the get_string function, meaning that it will disappear after get_string returns, and it will be useless to the caller.

Another possibility is

#include <stdlib.h>

char *get_string(char *q)
{
    char s = malloc(100);         /* better */
    if(s == NULL) {
        fprintf(stderr, "out of memory!\n");
        exit(1);
    }
    printf("%s",q);
    scanf("%99s",s);
    return s;
}

This will work just fine. Note that I have checked to see whether malloc succeeded. (If it fails, it returns a NULL pointer.) But now we have the issue that some memory has been allocated which might never be freed. That is, get_string returns a pointer to dynamically-allocated memory, and it's the caller's responsibility to free that memory when it's no longer needed. The caller doesn't have to, but if there end up being 1,000,000 calls to get_string, and if none of the allocated blocks ever gets freed, that's a lot of memory wasted.

Upvotes: 2

Garrigan Stafford
Garrigan Stafford

Reputation: 1403

First as other people have noted in the comments the Typedef in this case isn't very helpful as it hides the fact its a pointer. Also char* is vary commonly used and not a type complicated enough for a typedef IMO.

For your other issues the problem appears to be that you are thinking of the value as a C++ string instead of a char pointer. In C there aren't string objects but instead people use char* which can pointer blocks of chars and we determine the end of the string by putting a null character at the end of list of characters.

So the reason you can't print the NULL string is because it is undefined behavior to pass a NULL pointer to printf. When you change it to s = malloc(sizeof(string)); the pointer is no longer null but instead pointing to the start of a block of memory that is sizeof(string) bytes long. You should be doing malloc(sizeof(char)*strlen(q)); instead so you have a block of memory holding a string with the length of string q instead of just one character. More generally it would be malloc(sizeof(char)*NUM_CHARS);.

When it come to the free call. You can't call free(s) after return s; because no statements after return s; will occur because the function has returned and no longer executing. As for calling before, calling free(s) deallocates that block of memory that s is pointing too from the malloc(sizeof(string)) is pointing to. Here you have to remember that the function isn't returning the memory or the string but instead it returns the pointer to the string. So if you delete the memory the pointer is pointing to then you lose it once you return.

Upvotes: 0

Related Questions