简体   繁体   中英

C++ Memory Allocation Of A Variable That Is Not Initialized (32bit Machine)

I noticed that if you allocate a char array inside of a function like this

void example()
{
    char dataBuffer[100] = { 0 };
}

then examine the disassembly of the function with IDA that this actually inserts a call to memset() in order to initialize the char array . Looks something like this after I reversed it

memset(stackPointer + offset + 1, 0, 100);

The raw assembly looks like

addic     r3, r1, 0x220
addic     r3, r3, 1
clrldi    r3, r3, 32
li        r4, 0
li        r5, 0x64
bl        memset

But If I were to change the example() function to

void example()
{
    char dataBuffer[100];
}

Then the call to memset() is not inserted I noticed when examining the disassembly in IDA. So basically my question is, if the char array is not initialized to zero will it still be safe to work with? For example

void example()
{
    char dataBuffer[100];
    strcpy(dataBuffer, "Just some random text");
    strcat(dataBuffer, "blah blah blah example text\0");//null terminator probably not required as strcpy() appends null terminator and strcat() moves the null terminator to end of string. but whatever
}

Should I expect any UB when writing/reading to the char array like this even when it is not initialized to zero with the inserted memset() that comes along with initializing the char array with = { 0 } ?

It's perfectly safe to work with it as an array with garbage data. This means writing into it is safe, reading from it is not. You simply just don't know what is in it yet. The function strcpy doesn't read from the array it gets (or more specifically, from the pointer it gets) it just writes onto it. So it's safe.

After you are done with writing into your char buffer. When you come to use it, you are going to go through it until you encounter a null (0) character. That null character will be set there when you wrote into it last. After that null character comes garbage if you didn't initialize it, and comes 0's if you did. In both cases, it doesn't matter since you are not going to read past the null character.

See: http://www.cplusplus.com/reference/cstring/strcpy/

it uses a very similar example to the code you provided.

The line

char dataBuffer[100];

calls the variable dataBuffer into existence, and thus also associates memory with it. However, as an optimization, this memory is not initialized. C is designed not to perform any unnecessary work, and you are working in the C subset of C++ here.

That said, if your compiler can prove that you don't actually use the memory, it does not need to allocate it. But such an optimization would not be detectable from within your running, standard compliant code by definition. Your code will run as if the memory had been allocated. (This as-if rule is the basis for pretty much all optimizations that your compiler is allowed to perform.)

Your strcpy() and strcat() calls are fine, as they do not overrun the allocated buffer. But better forget that strcpy() and strcat() exist, there are better, safer functions to use nowadays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM