Why does this code corrupt memory?

你。 提交于 2019-12-04 13:13:25

You haven't mentioned what environment this code runs under. It could be you are blowing your stack. You are declaring a 32767 byte array on the stack in RiseWindows::Print. On some embedded system environments that I am familiar with that would be bad news. Can you increase your stack size and/or allocate that buffer on the heap just to test that theory? You may want to make that buffer a std::vector instead, or possibly a private member vector to avoid allocating and reallocating it every time you call Print.

Along those lines, how big is MAX_PRINT_OUTPUT?

Probably not the bug you're asking about, but in your loop you are double incrementing pBuffer in some cases, which could be pushing you over the end of buffer because you only check against length-1 (for null termination).

Random guess: I get the feeling that the problem is caused by this line in Printf:

char formattedOutput[MAX_PRINT_OUTPUT];

The reason I think this is because you've got some obviously declared pointers and some obviously undeclared pointers. An array of chars is a pointer - no way around that but it's not obvious. In the function definition of Echo args is defined as a TWO DIMENSIONAL ARRAY because you have it as

*args[MAX_COMMAND_ARGS]

Do you want that? My guess is that something is unintentionally being passed as a reference instead of a value because what is a pointer vs. array is vaguely defined and you're passing a pointer to a pointer which is the start of an array instead of a pointer that is the start of an array. Since you said that it gets corrupted when you enter RiseWindows::Print my guess is that you're passing the wrong thing.

In addition, a const pointer to a char only preserves the value of the pointer as far as I know, not the value of the contents at the pointer.

Did you try the divide and conquer strategy?

  • Start commenting out lines until it work.
  • Once it work correctly uncomment lines until you hit where the error is.

Watch the memory pointed by args[] in separate window while you do step by step also can be helpful.

Might I suggest stepping through with a debugger to see where the code corrupts?

while (pOutput[i] && ((pBuffer - buffer) < sizeof(buffer) - 1))

change to:

while (pOutput[i] && ((pBuffer - buffer) < sizeof(buffer) - 2))

you are writing 2 characters at a time so you need to make sure you have room for two characters.

not sure if it's how it's supposed to work or not but Echo doesnt print out the first element of args

// Changed i=1 to i=0;
for (int i = 0; i < argCount; ++i)
{
    Printf("%s ", args[i]);
    Printf("\n");
}

You want to move your #define out of the function call to the top of the file:

Preprocessor directives can appear anywhere in a source file, but they apply only to the remainder of the source file.

This probably isn't causing the corruption in this case, but it's non-standard, and could easily cause problems down the line.

The working theory is that we're blowing the stack with:

char buffer[CONSOLE_OUTPUT_SIZE]; char *pBuffer = buffer;

Instead try:

char *pBuffer = new char[CONSOLE_OUTPUT_SIZE];

And then remember to call delete [] pBuffer at the end.

I haven't really investigated this, but you've got your types mixed up... This is extremely pedantic, but it does make a difference in C.

Here, you have a single array of char.

char formattedOutput[MAX_PRINT_OUTPUT];

And here, you have a function that expects a const char pointer.

void RiseWindows::Print(const char *output)

Try:

void RiseWindows::Print(const char output[])

Additionally, I notice you are modifying the memory in those buffers - are you sure you can do that? At the very least, I'm certain that you can't just arbituarily use more without allocating more memory. (Hint hint!)

I would allocate my own array, and copy the string into it. I would then use string functions to replace the newlines as applicable.

Finally, I STRONGLY suggest that you use std::string here. (Though you won't be able to put those into the varargs stuff - you'll have to use c-strings for those, but copy those back into std::string's when you can).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!