Can cout change the contents of a char array? - c++

To make this as quick and concise as possible, this is my code:
char* aiMove = getAIMove();
cout << aiMove;
cout << "\n" << numMoves << ": " << aiMove << "\n\n";
return aiMove;
And this is my output:
a0 a1
0: �����������������������7
So, the first line calls getAIMove() and assigns the return value (char*) to aiMove.
The second line prints aiMove (a0 a1).
The third line takes numMoves and aiMove into cout and prints it, but it's printing some strange value instead.
The 4th line returns aiMove, which I've inspected to be the strange value printed.
Why has the value of aiMove changed? It seems to only happen when I pass an integer value into cout (in this case, numMoves).
Please help!
Thanks,
Patrick :)
edit: another thing that I forgot to mention is that this strange behaviour only happens when this block of code gets executed for the first time, every following time it gets run during the program it prints fine.

This is a clear indication that getAIMove returned a pointer to memory that the system felt free to reuse. A subsequent allocation, from either the stack or the heap, overwrote the returned pointer.
There are lots of ways this can happen, this is probably the most common:
char *GetAIMove()
{
char buf[128];
strcpy(buf, "a0");
strcat(buf, " ");
strcat(buf, "a1");
return buf; // oops, buf won't exist after we return
}
Oops. This code returns a pointer to a buffer that ceases to exist as soon as it returns. A typical fix for this issue would be return strdup(buf);. Just remember that the caller of the function needs to free the string when it's done with it.
Here's another way:
std::string GetAIMove()
{
// ...
return foo;
}
char* aiMov e= GetAIMove();
// aiMove points to the contents of the returned string, no longer in scope.
The fix for this is std::string aiMove = GetAIMove. Now aiMove keeps the string in scope.
But the best fix is to use a string class specifically designed to hold strings all the way through:
std::string GetAIMove()
{
std::string foo;
foo = "a1";
foo += " ";
foo += "a2";
return foo;
}
std::string aiMove = GetAIMove();
Note that while this code appears to involve a lot of copying, in practice, modern compilers will make it efficient. So don't feel bad about keeping your code simple, logical, and easy to understand and maintain.

No, cout doesn't change the contents of the parameter.
You're probably doing something wrong beforehand and running into undefined behavior.

Related

Wchar_t empty unless "wcout" used [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
How to return local array in C++?
(12 answers)
Closed 7 years ago.
Ill start with an example of source code (that i modified for clarity so ignore variables like "someLetter"):
wchar_t *someFunction()
{
wchar_t str[1024] = L"";
for (int i = 0; i < 50; i++)
{
str[i] = someLetter;
}
str[51] = L'\0';
return str;
}
The above code simply adds wchars to w_char array and when for loop is ended, it ends the array with L'\0'. Variable ret should hold the string.
However, when I execute the code below, i get nothing (empty string).
wchar_t *result = someFunction();
wcout << result << endl;
This is where it gets weird. If i execute the code mentioned all above, I get nothing. BUT if I add wcout << str << endl; in someFunction(), everything seems to be working fine i.e. code below does what its supposed to do.
wchar_t *result = someFunction();
wcout << result << endl;
TL:DR
Code below doesnt print out "result". Instead it prints out nothing and result is blank. The problem is fixed if I add wcout << str<< endl; to someFunction(). Why is that and how can I avoid that.
wchar_t *result = someFunction();
wcout << result << endl;
You are returning a pointer to automatic storage that goes out of scope when someFunction ends, so there is no correct behavior; it is undefined what will happen if you access a variable after it's gone out of scope. If you really need to return a wchar_t*, you'll need to either use a static array, pass a pointer to a buffer into someFunction, or dynamically allocate memory (and make the caller responsible for freeing that memory). The best thing to do would probably be to use std::wstring instead of raw wchar_t*s.
This code cannot work as you return the address of a local variable. The memory of wchar_t str[1024] is freed until someFunction() returns to the caller.
Sidenode: It should be str[50] = L'\0'; and not str[51] = L'\0'
To get you code working you might either use a std::wstring and return a copy of it or allocate the memory for str on the heap using new[] and delete[] it later on.
You should probably get a bit more familiar with C++ before asking questions like this.

strcpy works fine, even though memory is not allocated

Below c++ program works fine, even though i have not allocated any memory to chr.
I went through google, SO and came across this
Why does this intentionally incorrect use of strcpy not fail horribly?
Here the program works fine for destination which has space less than the source.
Does that apply in my case also,strcpy writes into a random location in the heap?
#include<iostream>
using namespace std;
class Mystring
{
char *chr;
int a;
public:
Mystring(){}
Mystring(char *str,int i);
void Display();
};
Mystring::Mystring(char *str, int i)
{
strcpy(chr,str);
a = i;
}
void Mystring::Display()
{
cout<<chr<<endl;
cout<<a<<endl;
}
int main()
{
Mystring a("Hello world",10);
a.Display();
return 0;
}
output:-
Hello world
10
I tried the same thing with another c++ program, with any class and class member, and i was able to see the crash.
#include<iostream>
using namespace std;
int main()
{
char *src = "Hello world";
char *dst;
strcpy(dst,src);
cout<<dst<<endl;
return 0;
}
Please help me understand the behavior in the first c++ program.Is memory allocated somehow or strcpy is writing to some random memory location.
The behavior of your program is undefined by the C++ standard.
This means that any C++ implementation (e.g. a compiler) can do whatever it wants. Printing "hello!" on stdout would be a possible outcome. Formatting the hard disk would still be acceptable, as far as the C++ standard is involved. Practically, though, some random memory on the heap will be overwritten, with unpredictable consequences.
Note that the program is even allowed to behave as expected. For now. Unless it's Friday. Or until you modify something completely unrelated. This is what happened in your case, and is one of the worst thing to happen from the point of view of a programmer.
Later on, you may add some code and see your program crash horribly, and think the problem lies in the code you just added. This can cause you to spend a long time debugging the wrong part of the code. If that ever happens, welcome to hell.
Because of this, you should never, ever, rely on undefined behavior.
strcpy() is indeed writing to a random location.
And it's a blind luck if your program runs fine and nothing crashes.
You have created on object of MyString class on a stack. In that object there's a member pointer chr, which points to some arbitrary location. Does your constructor take care to initialize that pointer or allocate a memory for the pointer to point at? -- No, it doesn't. So chr points somewhere.
strcpy() in its turn doesn't care about any pointer validity, it trusts your professionalism to provide valid input. So it does its job copying stings. Luckily, overwriting memory at the location pointed by an uninitialized chr doesn't crash you program, but that's "luckily" only.
It is known that strcpy() can cause overflow errors, because there is no check made wherever the data will fit in the new array or not.
The outcome of this overflow may sometime never been noticed, it all depends on where the data is written. However a common outcome is heap and/or program corruption.
A safe alternative of strcpy() is the usage of strcpy_s() that requires also the size of the array. You can read more about the usage of strcpy_s() on MSDN or here
Actually, strcpy() does something like this:
char *strcpy(char *dest, const char *src)
{
unsigned i;
for (i=0; src[i] != '\0'; ++i)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
So, when you pass a pointer to some character array to strcpy, it copies data from src to dest until it reaches NULL terminated character.
Character pointer does not contain any information about length of string, so when you pass dest pointer, it copies data even though you haven't assigned memory to it.
Run this example code, you will get my point:
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char str1[] = "Hello_World!";
char str2[5];
char str3[10];
strcpy(str2,str1);
cout << "string 1:" << str1 << endl;
cout << "string 2:" << str2 << endl;
cout << "string 3:" << str3 << endl;
return 0;
}
This will not show any error but you can understand by my example that this is not a good practice.

lifetime of a temporary function parameter

Creating a temporary char buffer as a default function argument and binding an r-value reference to it allows us to compose statements on a single line whilst preventing the need to create storage on the heap.
const char* foo(int id, tmp_buf&& buf = tmp_buf()) // buf exists at call-site
Binding a reference/pointer to the temporary buffer and accessing it later yields undefined behaviour, because the temporary no longer exists.
As can be seen from the example app below the destructor for tmp_buf is called after the first output, and before the second output.
My compiler (gcc-4.8.2) doesn't warn that I'm binding a variable to a temporary. This means that using this kind of micro-optimisation to use an auto char buffer rather than std::string with associated heap allocation is very dangerous.
Someone else coming in and capturing the returned const char* could inadvertently introduce a bug.
1. Is there any way to get the compiler to warn for the second case below (capturing the temporary)?
Interestingly you can see that I tried to invalidate the buffer - which I failed to do, so it likely shows I don't fully understand where on the stack tmp_buf is being created.
2. Why did I not trash the memory in tmp_buf when I called try_stomp()? How can I trash tmp_buf?
3. Alternatively - is it safe to use in the manner I have shown? (I'm not expecting this to be true!)
code:
#include <iostream>
struct tmp_buf
{
char arr[24];
~tmp_buf() { std::cout << " [~] "; }
};
const char* foo(int id, tmp_buf&& buf = tmp_buf())
{
sprintf(buf.arr, "foo(%X)", id);
return buf.arr;
}
void try_stomp()
{
double d = 22./7.;
char buf[32];
snprintf(buf, sizeof(buf), "pi=%lf", d);
std::cout << "\n" << buf << "\n";
}
int main()
{
std::cout << "at call site: " << foo(123456789);
std::cout << "\n";
std::cout << "after call site: ";
const char* p = foo(123456789);
try_stomp();
std::cout << p << "\n";
return 0;
}
output:
at call site: foo(75BCD15) [~]
after call site: [~]
pi=3.142857
foo(75BCD15)
For question 2.
The reason you didn't trash the variable is that the compile probably allocated all the stack space it needed at the start of the function call. This includes all the stack space for the temporary objects, and objects that are declared inside a nested scope. You can't guarantee that the compiler does this (I think), rather than push objects on the stack as needed, but it is more efficient and easier to keep track of where your stack variables are this way.
When you call the try_stomp function, that function then allocates its stack after (or before, depending on your system) the stack for the main function.
Note that the default variables for a function call are actually by the compile to the calling code, rather than being part of the called function (which is why the need to be part of the function declaration, rather than the definition, if it was declared separately).
So your stack when in try_stomp looks something like this (there is a lot more going on in the stack, but these are the relevant parts):
main - p
main - temp1
main - temp2
try_stomp - d
try_stomp - buf
So you can't trash the temporary from try_stomp, at least not without doing something really outrageous.
Again, you can't rely on this layout, as it is compile dependent, and is just an exmaple of how the compiler might do it.
The way to trash the temporary buffer would be to do it in the destructor of tmp_buf.
Also interestingly, MSVC seems to allocate stack space for all of the temporary objects separately, rather than re-use the stack space for both objects. This means that even repeated calls to foo won't trash each other. Again, you can't depend on this behavior (I think - I couldn't find an reference to it).
For question 3.
No, don't do this!

returning pointer from function giving me random numbers

I am working on a small console game on my free time and have come across a bug I can't seem to fix no matter what I try. I have tried a lot of different things with the pointers so this is just the latest version of my code. I have been searching around and a few questions other's have asked indicated I may be experiencing a memory leak, or that I am reading values from beyond my arrays (don't understand how). However, those questions have been solved without leaving me any hints as to what is wrong with my code.
Basically, I have a function called int * spendAttribute(int point);
Since anything created in that function is out of scope in my main() I want to take 6 int out of that function, and bring them into my main().
I thought "hey why not use a pointer!" The function is supposed to return a pointer to an array created during the function, and paste it to another pointer created in main(), this has worked once before in my main(), but now it's not working and I have no clue why.
int * spendAttribute(int point)
{
string choice;
int hp,hpT,endur,endurT,dmg,dmgT,armor,armorT,agility,agilityT,evade,evadeT;
while(condition)
{
//do a bunch of junk ....
}
int stats[6] = {hp,endur,dmg,armor,agility,evade};
//some cout testing to see if values are correct (they are)
int* p_stats = new int [6]; //create a block of 6
p_stats = &stats[0]; //point to the first value of stats array
return p_stats; //return pointer
delete [] p_stats; //delete blocks
}
Note: I have tried without deleting the blocks and it still does not work. I tried this since I read that it might be a memory leak.I have tried it without using new at all.
main()
{
//.... some junk
while(main game loop)
{
int * pointer;
cout << "*************** Enter 'begin' to commence ****************** " << endl ;
cout << "*************** Enter 'spend' to use new attribute points ** " << endl ;
cin >> beginChoice; //declared before while loop
if(beginChoice == "spend")
{
cout << "total attributes: " << Bryan.returnAttribute() << endl ;
pointer = spendAttribute(Bryan.returnAttribute()); //copy pointer
cout << "TEST: " << endl ;
cout << pointer[0] << endl ; //out put is a bunch of random numbers..
cout << pointer[1] << endl ;
cout << pointer[2] << endl ;
cout << pointer[3] << endl ;
cout << pointer[4] << endl ;
cout << pointer[5] << endl ; //SOME DAMN BUG HERE
Bryan.addMaxHp(pointer[0]);
Bryan.addEndurance(pointer[0]);
Bryan.addDmg(pointer[0]);
Bryan.addArmor(pointer[0]);
Bryan.addAgility(pointer[0]);
Bryan.addEvasion(pointer[0]);
//after this character ends up having some ridiculous stats like -564553535%
//evasion or 9879967856 armor...
}
}
}
This method of transferring the array over to main worked for me before in this exact file, so I don't know exactly how I am getting these errors or what's causing them. I have even tried deleting the previous pointer used to see if thats what was causing it but it wasn't.
Please Halp.
Because you return a pointer to a local variable, and when that local variable goes out of scope you have a stray pointer.
And no, your allocation doesn't help, as you reassign the pointer to point to the local array, instead of copying into the allocated area. This of course means you also have a memory leak.
Regarding memory leak, you will still have a memory leak even when you fix the above problem. The reason being that you return from the function before you delete[] the pointer, and return returns from the function immediately, all code after a return statement is dead code. That means every time you call the function, it will allocate new memory which will never be free'd.
There are two obvious solutions to both the problems above: One is to allocate memory, copy the array into the allocated memory, and returning the pointer, and in the caller you do delete[] on the pointer.
The second solution is to pass in an array as argument, and use that instead of the local stats array.
p_stats is a pointer to int.
First you assign it to a newly allocated place in memory.
Then you move the pointer to point to local storage and return that. My guess is that you really wanted to return stats. Your options are:
Returns std::vector< int >. Probably simplest.
Modify your function to take a buffer to data and a length and fill it in.
Return std::array if available and you know it will be a fixed size of 6.
Although you could copy the data into p_stats then return that, it is not ideal because the calling function is then responsible to delete the data later.
If the fields have different meanings, you might want to create a struct with meaningful names for the values, and get your function to return that struct. e.g.
struct SpendAttribute // in header
{
int hp;
int endur;
int dmg;
int armor;
int agility:
int evade
};
SpendAttribute spendAttribute( int point )
{
SpendAttribute res;
// enter code here
return res;
}
There is a final option of putting the data into a smart-pointer like boost::shared_array<int> or you can use shared_ptr with an array-deleter.
For now, just return std::vector<int>

C++ parameter passing queries (code examples and outputs included)

Again here i am because the course material for C++ was not taught very well at all. The question gives use several function definitions and calls to these functions and expects us to state the output and what exactly is going on. I have executed these functions and tried to come up with some rationale to what is happening but if someone could help me out that i would be very grateful.
function definitions (The names are all as given. I know the names are not very good):
void MyIncrementFirst(int * i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int ** i) {
*i = new int(0);
}
void MyIncrementFifth(int *& i) {
i = new int(69);
}
The calls to these functions have been defined as:
int * a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " << *a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
Which produces the following:
first 43
second 43
third 44
fourth 0
fifth 69
Some of this syntax i have not seen before (e.g. *&) so i maybe completely wrong here.
First:
This seems simple enough. I am passing in a pointer to an integer, and then de-referencing the pointer and incrementing its value, so instead of incrementing the pointer i am incrementing the actual value it is pointing to. No memory allocation is used, and this function uses pass-by-reference in order to modify the value.
Second:
This is similar to the above, as the pointer is de-referenced to get the integer value from the pointer rather than the memory address. Now this function uses pass-by-value so a copy of the variable is used in the functions execution. This means that incrementing a here, will have no impact on the variable you passed in, the value of a will remain as 42, but the copy of the passed in variable will have its value changed to 43 during the functions execution.
Third:
My understanding is that the '&' operator is basically saying 'the memory address of ...' so this function will take the memory address of the passed in pointer, locate the value it points to an increment this by one. That is why 43 is printed. This is using pass-by-reference.
Fourth:
If i remember correctly the '**' syntax means a pointer to a pointer. This means that when passing &a to the function you are passing the memory address of the pointer so when you de-reference this pointer and set its value to a new int(0); you are actually overwriting the exiting data at this address (42 in this case) so the value 0 is printed. This uses pass-by-reference.
fifth:
I have not seen this syntax before (*&). I have looked up this syntax and i think it is basically saying 'pass me by reference not value' so it seems to be the same as de-referencing the pointer as mentioned earlier. Again, because this is pass-by-refence not value when the value is set to a new int(69); the current data at that location is overwritten thus 69 is outputted.
Edit: Forgot to include my question! I want to know if my thinking is correct, this is all exam prep so i want to be sure i am doing it correctly.I just want to make sure my logic is correct and if i have done anything wrong or missed anything would somebody be able to steer my in the right direction
Edit: (based on some commenter feedback)
Everything you have is mostly correct, save some confusion on your output values. However, what you have in #4 and #5 is actually not overwritten data, it's actually new data at a new address, which is assigned to the variable i. This is part of what an earlier commenter said about a potential for a memory leak. Since you're not deleting the old address before assigning a new one, that's where it could occur.
The &* syntax in the last one is a reference to a pointer. It's essentially the same as int** except you don't pass &a as the argument, it's just a
What you have there for number 5 is basically correct, but the reasoning behind it is missing the meaning of &*
You might want to clarify if you've run each of these function calls sequentially or one at a time, since your output is incorrect if you'd indeed run them sequentially as written.