1

I´m a bit confused with these 2.

I have a function called check that does the following:

bool check(const char *word)
{
    char newWord[LENGTH + 1] = "";
    
    for (int i = 0; word[i]; i++)
    {
        newWord[i] = tolower(word[i]);
    }
}

Now for example if I use ="", the variable newWord will have all of it´s values as '\0' anytime I run the function check();

But when using char newWord[LENGTH + 1]; the variable seems to keep the old values even after my functions has returned, so when I do check() again, the char newWord already has values from the previous time I ran that function.

I know this is related to pointers and memory allocation but I just cannot seem to get how this works.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Nuno Carro
  • 75
  • 1
  • 8
  • No, this is not related to pointers at all. It is purely about initialization of non-static variables. Only variables with static lifetime are initialized. Other variables are not initialized at all. It does not matter whether it is a pointer, an array, an integer or any other data type. – Gerhardh Nov 10 '20 at 11:32
  • Does this answer your question? [Why are global variables always initialized to '0', but not local variables?](https://stackoverflow.com/questions/14049777/why-are-global-variables-always-initialized-to-0-but-not-local-variables) – Gerhardh Nov 10 '20 at 11:35
  • thanks guys im going to dive into this. i think i understand a bit better now – Nuno Carro Nov 10 '20 at 11:37

3 Answers3

1

The values that you find after running check() twice are still garbage values. When you allocate some memory using

char newWord[LENGTH + 1];

You are always getting "some" memory that the operating system handles you (in laymen-terms), having initially garbage values. It is just a coincidence that you're getting the same memory blocks that you got from the previous call to check().
However, when you do:

char newWord[LENGTH + 1] = "";

You are explicitly initializing those memory blocks to \0.

Maaddy
  • 618
  • 5
  • 13
  • 1
    Would you consider then the second way of initializing my array the best proccedure, if i dont have a value ahead of time, i should initialize to an empty string? What you are saying makes sense. Thank you – Nuno Carro Nov 10 '20 at 11:45
  • Yes, indeed. It is a good practice to always initialize any variable or a block of memory you allocate. Because this will prevent you from going into "it works on my machine" things, where you have a working code simply because the garbage values (like this example) were initialized to something that made your code work :/ so, yes, always initialize your variables :) – Maaddy Nov 10 '20 at 11:49
1

It's not a fancy answer, but compilers (and versions of compilers) have different opinions on whether to initialize memory before you use it. Unless things have changed recently, the only variables that get automatically initialized are variables with a static scope (global variables and those explicitly marked static).

For everything else, certain compilers might set everything to zeroes (or another value for debugging), but most won't add that small overhead to your program, when you're probably just going to assign a value of your own, soon enough. One of the biggest debugging effort of my career was because we changed C compilers from one that didn't pre-initialize variables (like most do) to one that did, exposing a bunch of errors my predecessors didn't catch (assigning to the wrong variable, looking for non-zero values and suddenly finding them), so it's an important feature to know about.

The key to your question, though is "seems to keep," because it's only an accident that the old string is still in the right position. If you call another function between check() calls, you'll start to see different scratch memory.

Moral of the story? Always initialize every one of your variables, unless you absolutely know that it's going to get a value before you use it.

John C
  • 1,931
  • 1
  • 22
  • 34
  • 1
    Thank you i think i understand it now. Makes total sense, if you don´t have a value for that variable yet, initialize it to an empty string or 0 to avoid garbage values. – Nuno Carro Nov 10 '20 at 11:47
  • 1
    Static is a storage duration, not a scope. Storage duration is when during program execution an object exists. Scope is where in source code an identifier is visible. – Eric Postpischil Nov 10 '20 at 12:02
  • 1
    How would I initialize an array of structs then? because i cant seem to assign it to null: node *table[N]; node *table[N] = NULL; //doesnt work – Nuno Carro Nov 10 '20 at 12:17
  • @NunoCarro, your best bet is going to be [`memset()`](https://en.wikibooks.org/wiki/C_Programming/string.h/memset), because there's (unfortunately) no direct answer. – John C Nov 10 '20 at 15:36
  • @EricPostpischil, it depends on who you are. From the perspective of writing a compiler that implements the C compiler, you're 100% right. From the perspective of more general programming language design, storage duration *is* just C's jargon for what everybody else calls scope. – John C Nov 10 '20 at 15:43
  • @JohnC: No, it does not depend on who you are. The terms are formally defined in the C standard, and both general C programs and compiler implementors should understand them. They have different effects, properties, and consequences. Using the terms incorrectly causes confusion that has to be corrected eventually. – Eric Postpischil Nov 10 '20 at 16:01
1

If you don't initialize a local variable, it has an indeterminate value. Which could be anything, including random "garbage" or left-overs sitting in RAM memory since previous execution. There are no guarantees of what value you will get - and that's it.

Accessing such an uninitialized variable's value might also invoke undefined behavior in some cases:
(Why) is using an uninitialized variable undefined behavior?

Lundin
  • 195,001
  • 40
  • 254
  • 396