Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a pointer array of Word (objects) and I have to assign another object of type Word to this objects array.
Using this two lines of code I put the new object w inside my objects array (word).
Word w = Word(new_word, len);
this->word[index - 1] = w;
Then I print my objects array and everything comes out right
for (int k = 0; k < this->len; k++) {
cout << this->word[k].getChars() << endl;
} // End of function 1
After "End of function" we return to the main class that call to another function.
This function print the objects array again but now the function does not print the w object that I insert in the previous function.
Second function
for (int k = 0; k < this->len; k++) {
cout << this->word[k].getChars() << endl;
} // End of function 2
Can anyone explain to me why this is happening and how it can be arranged.
Though it's difficult to be certain (since we don't have the rest of the function to look at), it seems that you may have a dangling pointer issue.
When you declare Word w = Word(new_word, len); in your function, you're declaring it as a local variable, placing it on the stack. Adding this to the array doesn't cause any issues when you're still in the function, but once you return from where you came, the function's memory - including Word w - is destroyed. When you try to access that memory location again by printing it from the array, you're looking for a variable that no longer exists, and thus get undefined behavior.
Luckily, you're using c++, and heap memory management is fairly well supported! I would consider implementing word as an array of pointers. If you then try something like this...
Word *w = new Word(new_word, len); //use "new" to create an object on the heap - persistent after you leave the function!
this->word[index - 1] = w; //make sure this->word is now an array of Word*; it seems to currently be an array of Word
...you may find the problem solved. Just don't forget to free it when you're done!
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
Today, I found a small problem when creating dynamic arrays.
I use the resize () function to change the size of the array. In the resize () function, I created a temporary array "newData", and then I assigned it the new size I wanted. After assigning the value of the initial array "Data" to it, I set
Data=newData;
At this time, the task of the resize () function has been completed. Before exiting the function, I had a whim and deleted the space of "newData" by
delete [] newData;
After that, when I output the value of Data [2], I can still output the value.
Now I'm a little confused. "Data" and "newData" should be pointers, right? When I use the statement "Data=newData;", what "Data" points to should become the address space that "newData" points to. If I delete the address space of "newData", shouldn't the space corresponding to "Data" also disappear? Why can I continue to output values?
The following is the complete code
#include<iostream>
using namespace std;
int Length = 0;
int* Data;
void resize(int,int *);
int main()
{
Data = new int[5];//This is the space I allocated for the initial array
for (int i = 0; i < 5; i++)
Data[i] = i;
Length = 5;//There are five data in the initial array
int newLength = 10;//I started distributing new sizes to the initial array
resize(newLength,Data);
cout << Data[2];//The output is still 2
}
void resize(int newLength,int *Data)
{
int* newData = new int[newLength];//A temporary array
for (int i = 0; i <Length; i++)//Move the value of the original array to the temporary array
{
newData[i] = Data[i];
}
Data = newData;
delete[] newData;//Delete the space where the temporary array is located
}
You (try to¹) access deleted space; that's what is called undefined behaviour in C++: Anything might happen. There might be the original values, the might be some other data you worked on put there, there might be the value 0xdeadcafe all over the place, your program might crash or cause a fire, delete all files or give an attacker access.
It's undefined, and you found one of the things that might happen.
¹ From your question, that was your intent. Luckily, you messed up your resize function prototype, and pass in the Data pointer by value, not by reference, so that your Data = newData; doesn't do anything outside your function. That together with the global variables on top of your files: Maybe revisit what a function is and what scope and pass-by-reference mean!
Generally, you're a C++ beginner: cool! That's a good path to be on.
Maybe do less with new and delete. It's been a while since I used these two, they're becoming a rare pattern in modern C++! C++ can very well (for the most part) be written without these, completely, by using other methods, where your memory allocation and deallocation are linked to objects' lifetimes. And that's way less error-prone, and honestly, easier to understand.
For example, in your use case, instead of your Data, newData, new and delete handling, you could have said std::vector<int> Data(Length);, have put the values in exactly as you did, and then just called Data.resize(newLength);. No need for manually knowing where to delete your memory!
I'm not sure why you're doing this, but you're declaring your variables globally. That's a bad idea from start to finish, so, um, just don't do that: Declare variables in the scope you need them, which would be your main function. Maybe someone who has had a very early 1970's copy of some C book confused obsolete C with the C++ you should be taught? I don't know. Global variables are generally a bad idea.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
A picture of memory output debugging stuff
the W, S, G are W( base class ) S( derived from base W ), G( derived from base W ). S has two extra floats that W doesn't, G has a bool W doesn't.
the numbers following the letters is just sizeof( W/S/G ).
the ants are made like so
W* _ants = new S[ 6 ];
and the function giving the problem is called like so
for( int i = 0; i < 6; i++ )
{
std::cout << "Ant " << i << ": " << &_ants[ i ] << std::endl;
_ants[ i ].update();
}
update is a non-virtual method from W, though it does call a virtual method within it. I have tried removing the virtual method but it still crashes.
I'm pretty sure the problem is that the array is trying to allocate for W but since it is 8 bytes smaller than S _ants goes off track at 1 iteration, is there anyway I can get _ants to allocate the correct amount per iteration without trying to change it to S* or at least keep it on track somehow?
This is one of the best reasons you should not use C-style arrays in C++ unless you have no choice. The language can't easily distinguish between a pointer to a single instance and a pointer to an array, so it cannot detect when you use the latter in an instance where only the former is legal.
W* _ants = new S[ 6 ];
This is setting you up to fail. The array of 6 S objects lays them out in memory sizeof(S) bytes, plus padding, apart.
So what's going on here? The type on the right is S*. While here it points to an array, the conversion to W* is allowed because the same type could point to a single object. While converting a pointer to a single instance of a derived type to a pointer to its base is perfectly legal, it is impossible to do the same thing for a pointer to an array. The memory layout is just not the same.
_ants[ i ].update();
And then here you fail. This adds i * sizeof(W) bytes to _ants, which does not match the layout.
See here for more information.
Your reasoning is correct for why it's misaligned. You shouldn't use arrays polymorphically. Instead of having an array of Ws, use could use an array of W*s. This is one way to work around this problem:
W** _ants = new W*[6];
for( int i = 0; i < 6; i++ )
ants[i] = new S(...);
}
//...
for( int i = 0; i < 6; i++ )
{
_ants[ i ]->update();
}
Your problem is that your memory is not going to line up. When you do
W* _ants = new S[ 6 ];
You now allocated enough space for 6 S but you are using a pointer of type W to traverse it. Since W is smaller than S after the first iterator you will point to memory that is the end of the first S and part of the second S
If you want to store 6 S* in a W* container then I suggest you use a std::vector and do something like:
std::vector<W*> data;
for (int i = 0; i < some_number; i++)
{
data.push_back(new S());
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have some code here which reverses an array of characters:
#include <iostream>
#include <string>
using namespace std;
char s[50];
void reverseChar(char * s)
{
for (int i=0; i<strlen(s)/2; ++i)
{
char temp = s[i];
s[i] = s[strlen(s)-i-1];
s[strlen(s)-i-1] = temp;
}
}
int main() {
cout << "Hello, this program reverses words." << endl << endl;
cout << "Enter in a word, no spaces please:" << endl;
cin.getline(s, 50);
cout << "This is the word, it has now been reversed:" << endl;
reverseChar(s);
cout << s;
return 0;
}
In the for loop can someone explain what is going on at the hardware level. I understand 'temp' is allocated to a byte, which is assigned to the value of s[i].
Is memory allocated to everything?
The equals sign, s[i], etc?
After the byte is assigned to the value in s[i], s[i] is assigned to some other value in array s. This other value is then assigned to temp.
I'm having trouble understanding where all these bytes are going, and how they are being manipulated by C++.
I understand that in the line:
s[i] = s[strlen(s)-i-1];
The placeholder values are being swapped?
In this line:
s[strlen(s)-i-1] = temp;
The 'copied' value is sent to 'temp'. But what happens to this temp value afterwards, does it become the new 'temp' once the for loop reiterates?
In the for loop can someone explain what is going on at the hardware
level. I understand 'temp' is allocated to a byte, which is assigned
to the value of s[i].
Is memory allocated to everything?
Yes, it is allocated, but on the stack. You need to learn the difference between stack and heap.
Yes, all variables are represented in some form of memory. But then again, based on the context, it could be either a stack or a heap.
The equals sign, s[i], etc?
Equals is an operator, to inform the compiler that an assignment operation is taking place, so no memory is required for that.
s[i], on the other hand, is an array object, represented in the stack memory.
The 'mirrored' value is sent to 'temp'. But what happens to this temp
value afterwards, does it become the new 'temp' once the for loop
reiterates?
since, in the loop you have declared temp as,
char temp;
a new variable temp, is created in the stack for every iteration.
I strongly recommend that you read about memory organization in a typical operating system. You can start with the basics from here.
Edit: Also note that based on the scope of the variable, the compiler automatically de-allocates memory for a stack variable based on its scope. For the temp variable above, its scope ends at the end of for loop, and hence it is destroyed at that point. Hence the compiler does not end up allocating a character space of memory for every iteration.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i am trying to generate an array which may be independant of dimensions. i tried doing this
#include <iostream>
using namespace std;
class array3d
{
public:
array3d(size_t* d, int dims)
{
int all = 1;
size_t* dimensions;
int* array;
for (size_t i = 0; i < dims; i++) {
all = d[i];
dimensions = new size_t[dims];
array = new int[all];
std::cout << array[i] << std::endl;
}
}
};
int main()
{
size_t d[6];
d[0] = 2;
d[1] = 3;
d[2] = 4;
d[3] = 2;
d[4] = 3;
d[5] = 4;
array3d arr(d, 6);
return 0;
}
when i compile it i end up with an array of zeros alone, i am not able to find where i going wrong. can anyone help?
I cannot really understand the logic behind you code, but if you simply want to see something printed you probably meant to do this:
array = new int [all];
//write something here first!
array[i] = some_value; <--- Note that this may access past the end of the array
std::cout << array[i] << std::endl;
Or more likely you wanted this:
std::cout << d[i] << std::endl;
Note1: You should really listen to 0d0a and use std::vector unless you really need arrays
Note2: You're doing some signed to unsigned comparisons (i < dims) - you might want to take care of those too
array = new int[all]; does not initialize the allocated memory. It will just make the allocation from heap, but leave the contents of memory as it was (or, actually, accessing the allocated but uninitialized memory may be Undefined Behaviour, strictly speaking).
You see zeros only by chance, because the memory happens to contain zeros. It is zeros probably because it has not been allocated, used and released by your program yet, and OS filled it with zeros before giving it to your program.
Additionally, std::cout << array[i] << std::endl; will be buffer overflow, if i>=all. Why do you do that anyway?
And finally, your code leaks memory like crazy. Your loop loops dims times, and with each iteration you do two allocations with new, but then you lose the returned pointers.
In short, use std::vector in C++, (almost) never use plain C arrays. If you have a clear use case for a fixed length array, use std::array. Furthermore, most of the time, if you are using naked pointers in C++ application code, you are not doing it right. Use smart pointers. This applies especially, if you are learning C++ today. Learn the modern way of doing things, it will make your life so much easier, while improving quality of your code.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am making a simple Lottery program - and am struggling with implementation. I have a class called 'Ticket Line' this class simply holds 6 numbers that the player is playing a lottery for.
What I want to do, is generate 6 randomly (got function for this already) and then store that in another class as values. To do this, I am using the following code:
class Draw
{
private:
int drawID;
TicketLine* DrawnNumbers;
bool drawn;
}
When a Draw is completed I want to generate the Random Numbers ( from the TicketLine class) and then for the Draw to be able to store those numbers into its Draw File.
How would I be able to access the functionality of the DrawnNumbers class - and store the results from the getTicketNumbers.getTicketLine()function.
int* getTicketNumbers(void) { return DrawnNumbers->getTicketLine();};
The program crashes the following code:
//int *ptr[6] = getTicketNumbers();
int *ptr[6] = getTicketNumbers();
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
TicketLine class:
private:
int select[6]; //Array of Ticket Numbers.
int* getTicketLine(void) { return select; };
I am willing to offer a couple of virtual beers to the solution. I am as yet to find a good online pub - if you know of one then please do let me know :-)
Thanks,
Without knowing any more, this line:
int *ptr[6] = getTicketNumbers();
is very suspect.
Why? Well, we haven't seen the implementation of getTicketNumbers so we don't know if it's actually allocating memory for 6 and returning such an array.
Also, you are printing the values of pointers here:
for (int x = 0; x < 6; x++){
cout << ptr[x];
}
Where, if you intended to actually print the int values, you'd say something like this:
for (int x = 0; x < 6; x++){
cout << *(ptr[x]);
}
My guess is that you are either:
Going out of bounds of an array that was (not) allocated, or,
Modifying actual pointer values somewhere instead of the integers they point to (as indicated by your lack of dereferencing ptr[x] in your print statement)
Edit
With more information, it seems you probably meant to say this:
int *ptr = getTicketNumbers();
instead of this:
int *ptr[6] = getTicketNumbers();
You should probably be doing some sanity checks as well to make sure that select is actually filled before calling that function (maybe giving it a default value of {0,0,0,0,0,0} in the constructor)
DrawnNumbers doesn't appear to be pointing to anything yet. It's a pointer, but to what?
Also, be careful about returning arrays that way. If the object or stack frame that the array resides in goes away, you'll be left pointing to bad things.