The scanf writes string to a pointer that does not have a defined size?

2

I'm trying to understand how strings work in C. I noticed that even though I can not define any limit for the TextoUm[] (which follows in the code below) in any part of the code, % can write a string to that vector correctly. But the same success does not occur if, in the scanf function, I replace the vector with a pointer of scanf (initialized with a string or not).

Below is a code showing exactly those cases of the vector and the pointer I mentioned (although I have read that "vector" is a "pointer").

#include <stdio.h>

int main ()
{
    char TextoUm[]="";
    char *TextoDois="";

    printf ("\n\n\tDigite um nome para \"TextoUm\":\n\n\t");

    scanf ("%s", TextoUm);

    printf ("\n\tO texto digitado foi: %s", TextoUm);

    printf ("\n\n\tDigite um nome para \"TextoDois\":\n\n\t");

    scanf ("%s", TextoDois); /* Aqui ele dá erro */

    printf ("\n\tO texto digitado foi: %s", TextoDois);

return 0;
}

After running this code in the debugger, it presented the following error:

  

Program received signal SIGSEGV, Segmentation fault.

On this error, on Wikipedia it says that it is an attempt to access an invalid or non-existent address, but this did not help me to understand why this error occurred only with the pointer and not with the vector. >

So my question is that of the title. Can char write a string to a scanf pointer, even though there is no limit size set for that pointer?

    
asked by anonymous 30.11.2016 / 23:24

1 answer

2

Run X right

Understand that C lets you do everything, and requires you to take responsibility for everything. This is both a positive and a negative point of language. She's close to the Assembly. So it just does not "work" which has no way of working.

But working and being right is quite different, I keep talking about it and almost nobody hears it. In C is even more important. You have to know every nuance of language before using it correctly. "I heard" it does not work well with C, you have to learn the right thing. "

Scanf()

First of all understand that scanf() is something useful and that in some applications can be used without problems, but the function is not used for more serious applications that need validation. Or it is only used as part of a larger algorithm.

One of the problems is that you can type anything and it accepts. You have some means of controlling this, but they are not always enough, and are often not used in simple examples. So it's easy to corrupt memory because the function writes to a location not reserved for the variable, after all C allows "everything."

Using it too much in a simple example may convey the idea that it is what you will use in real applications.

Declared variables

The two variable declarations work, but they are wrong, they do not reserve space for the string object, that is, it does not have a memory location available for the string to be stored. You only have one memory address somewhere, but this place is not set and reserved. To understand better read What are and where are the "stack" and "heap"? .

The first statement should reserve space for the string in the stack , but the placeholder is 0. Or would it need to put the size to be reserved in the brackets, or would put a string of the desired size (the compiler counts how many).

The second statement should reserve space for the string in the heap (probably), but this is not even attempted. The correct one would be to call the malloc() function that requests memory for the operating system (or the internal system) and returns the address of this placeholder.

The size value used will only reserve memory, it will not impose any limit on anything in C. If your code tries to write outside this reserved area, it will work. But it will give you a huge huge problem , losing data, crashing the application (if you're lucky) or opening up security holes, since it is not the right one.

Something like this works and is almost certain (still not a secure code):

#include <stdio.h>
#include <stdlib.h>

int main() {
    char TextoUm[10]; //note a mudança aqui
    char *TextoDois = malloc(10); //note a mudança aqui
    printf("Digite um nome para \"TextoUm\":\n");
    scanf("%s", TextoUm);
    printf("O texto digitado foi: %s", TextoUm);
    printf("\nDigite um nome para \"TextoDois\":\n");
    scanf("%s", TextoDois);
    printf("O texto digitado foi: %s", TextoDois);
}

See working on ideone and on CodingGround .

In his code, nothing was reserved in heap and he got a wrong address (where "" was) and that address caused a memory error because he could not write to it of protected memory).

Then you can use char pointer, but you have to initialize correctly. The error is not of scanf() , it is just the symptom that something was done wrong before.

The array of char seems to have worked correctly, but just by coincidence and because it is an exercise, if it were a real application, it would be more problematic. It's a worse mistake because it was not detected.

Conclusion

I'd like to say that array looks like a pointer but it's not the same thing >.

There are other points on the subject, but this can not be a complete tutorial. Actually I already answered here on the site about all that is learning. Just search or look at my profile. Other people have already responded. Examples:

01.12.2016 / 00:20