Array over written with last value assigned? - c++

I have a pointer to pointer array. I am assigning each row in the while loop below and the printf inside the while loop shows each is assigned my id number 1-20.
After, out side of the while loop I iterate through the array and every element is written with id 20?
Any help is greatly appreciated. (FYI- I am using the Template2doc library and example1.c, at the bottom here- http://www.algonet.se/~thunberg/template2doc/c_version/docs/index.htm)
Below code only shows problem area, I took out the rest.
char **tableData[500]={NULL};
char *myData[500][2];
while(rc == SQLITE_ROW){
tableData[r] = myData[r];
printf(*tableData[r]); <-- Displays id 1-20 fine
r=r+1;
}//end while
tableData[r+1] = NULL;//null terminated array
for (a=0; a<r; a++){
printf("\n");
printf(*tableData[a]); <--Displays 20 elements all of id 20?
}
outputFile=insertTableData(outputFile, dataMarker, fieldMarker, tableData);

You should create something that actually compiles and reproduces the problem. Not only will it help people help you, but in doing so you may very well find the problem yourself.
In your code excerpts we have no idea:
What rc is, how its value is set, or how its value is ever going to change and therefore terminate the loop
What the initial value of r is
What the actual contents of myData are
I created this code based on what you posted, which produces the same output from both loops. So either I've missed something in what you did post, or you left something important out.
int main( int argc, char** argv ) {
#define STRING char *
STRING dummy = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!##$%^&*()";
STRING *tableData[500]={0};
STRING myData[500][2];
int r=0;
while(r < 20){
myData[r][0] = dummy+2*r;
myData[r][1] = dummy+r;
tableData[r] = myData[r];
printf(*tableData[r]);
printf("\n");
r=r+1;
}//end while
int a;
for (a=0; a<r; a++){
printf(*tableData[a]);
printf("\n");
}
}

As pointed out, you are assigning Null at r+2 position. And are you in any way modifying tableData or myData in between the while and for loop?

How are you populating myData? I don't see a clear bug in the code example given, but I suspect the problem is that you are assigning a pointer to a buffer in myData without actually copying the contents, so that myData[0 .. r] all point to the same buffer, which will only store the most recent value read. Try this:
while(rc == SQLITE_ROW){
tableData[r] = myData[r];
if (r > 0)
printf(*tableData[r-1]);
r=r+1;
}//end while
That should print the ids from 1 to 19 fine. If it starts at id 2 instead of id 1, that suggests myData is not keeping a copy of the data, it's all pointing at the same location.

Well from what I can see right now, you're terminating your tableData at essentially r+2 from your last "duple" of information. Also, it might be a little clearer (maybe just for me) if you did tableData[0][1] or tableData[0][2] when printf'ing. That kind of makes it more clear that tableData is an index to a "structure" of 2, each containing a NULL terminated string. That might help with your debugging as well...

Try this for debugging then :
printf("Character at 0x%x : %d", tableData[a], *tableData[a]);
May be the bug is in what you took out ?

Yes, there were all pointing to the last value whe done. I went ahead and allocated memory space for each item, pointing to each accordingly.

Related

Random Symbols Getting Printed Without Initialization

I made a fairly short text-based animation program:
#include <iostream>
void animation(char words[], int sizeOfWords) {
for(int x = 0; x < sizeOfWords; x++){
for(double y = 0; y < 10000000; y++);
std::cout << words[x];
if(words[x] == '!') std::cout << std::endl;
}
}
int main() {
char words[] = {'H','e','l','l','o',' ','W','o','r','l','d','!','T','h','i','s',' ','i','s',' ','m','y',' ','f','i','r','s','t',' ','C','+','+',' ','a','n','i','m','a','t','i','o','n','!','H','o','p','e',' ','y','o','u',' ','e','n','j','o','y','e','d','!'};
int amountOfLetters = 0;
for(unsigned x : words) amountOfLetters++;
animation(words, amountOfLetters);
}
When I first made the program I forgot to initialize int amountOfLetters; to 0. That is when I got all these random symbols. The program is fine with or without initializing it. Just without assigning 0 to it, I get these extras in the end.
Without Initialisation Of The Variable will give the following result:
Hello World!
This is my first C++ animation!
Hope you enjoyed!
!
t ht ÉH P j     T j ­Ðou2ö¤.■   Á╬ouÈ╬ouht mzou
Process returned 0 (0x0) execution time : 11.466 s
Press any key to continue.
With Initialisation Of The Variable will give the following result:
Hello World!
This is my first C++ animation!
Hope you enjoyed!
Process returned 0 (0x0) execution time : 4.444 s
Press any key to continue.
You could try running the codes yourself if you want. I would just like to know why are these symbols being printed out. If you can help i'd appreciate it. If not thanks for stopping by.
This post isn't a duplicate of Why uninitialized char array is filled with random symbols?. I talk about passing the number of elements in an array and passing them as argument, afterwards looping through them. The other post is simply just talking about initializing an array Without Information in it and printing it. Meanwhile, again, I am talking about Having Information, just the size of the array holding them was the problem. Simply theirs is about printing an array with no elements, mine is about looping through an array with elements but, mistakenly making an error for the size.
Your animation function is accessing the char array by index, until the index == sizeOfWords. If amountOfLetters is not initialised you will start incrementing a random value, and will therefore read past the end of the array in animation. That, of course, has random values.
When I first made the program I forgot to initialize int amountOfLetters; to 0. That is when I got all these random symbols. The program is fine with or without initializing it. Just without assigning 0 to it, I get these extras in the end.
That's because without initializing amountOfLetters the amountOfLetters++; operation is undefined behavior.
amountOfLetters may have an arbitrary value at the beginning of the loop, as it was left on the stack from previous operations.
Also note that you could greatly simplify and improve your code just omitting the loop and write:
animation(words, sizeof(words));

C++: Iterate using enum type

I have these codes:
for (i = 0; i <= WND_WRL; i++) {
syslog(LOG_ERR, "TESTE i=%d WND_WRL=%d", i,WND_WRL);
}
for (i = 0; i <= WND_WRL; i++) {
syslog(LOG_ERR, "OnScrDsp for i=%d WND_WRL=%d", i,WND_WRL);
m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP);
assert(m_pWnd[i]);
}
The first for is only to explain my problem. The second is really my problem.
The source of second code can be found here:
https://github.com/HuayraLinux/intel-classmate-function-keys/blob/master/OnScrDsp.cpp
The problem:
WND_WRL variable came from
typedef enum {
WND_BRG,
WND_DSP,
WND_WRL,
} WND_ID;
struct.
In first code I can see i iterate until 2 (0,1,2) and WND_WRL will be always 2. The problem is in second code: even WND_WRL ever print 2 value, that for will iterate i until receive SIGV signal (11) and break my application (here it stop with i=384). I can understand why 384, I am not concerned about that.
What I do not understand is why the same condition provide different ways. If I change WND_WRL to number 2, I get correct code and correct app execution.
My first idea is the block of the second for maybe change WND_WRL value, but isn't happened.
I can understand if may be this code is writing in wrong memory position, but I always see WND_WRL with 2 value.
SOLUTION :
Change expression "i <=WND_WRL" to "i < WND_WRL" because m_pWnd size. It explain SIGV, but not explain why for continue until receive SIGV even if 2<=2 condition matches. Overriding memory we know can destroy a lot of things, but constants and code are read-only stack memory region, so access m_pWnd[3] and others i++ not explain why for does not stop.
Variable m_pWnd is defined in your source code as an array of pointers, with a size of 2, so valid index is 0 or 1.
GtkWidget *m_pWnd[WND_WRL];
But your loop goes i <= WND_WRL, so i=2 case will crash
m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP);

Print statement changing output of function?

I have a bit of c++ code that's supposed to look at the derivative of a function and collect the points that have a slope greater than some threshold. It's been giving me troubles, so I've been putting print statements everywhere to figure out what is going wrong. I stumbled upon a baffling issue where when I used std::cout<< to print the size of an array, it changed the output of the function! Here's the code snippet:
int* Tools::findPoi(float* y, int size, float threshold, int width, float step, int* outsize){
int poi[size];
float* derive = derivative(smooth(y,size,width),size, step);
int n = 0;
std::cout<<size<<" data size\n";
for(int i = 0; i<size; i++) {
if(derive[i] > threshold) {
poi[n] = i;
n++;
}
}
*outsize = n-1;
return poi;
}
without the commented out line "std::count..." I get 82 poi. But if I comment it out or remove it I get 84 poi. Nothing else changes, only this print statement. I am so confused as to why or even how it could possibly change the output. Any help would be greatly appreciated.
EDIT: ok, so actually, it's just random. The variable n is different everytime I run it, which leads me to believe that something weird is going on in memory.
There is a significant problem with the line:
return poi;
This returns the address of a local object. The array no longer exists when it goes out of scope at the end of the function. For a wonderful explanation see: Can a local variable's memory be accessed outside its scope?.
Since this is C++ and you want a dynamic array I suggest you use std::vector. It solves many problems such as this.

Debug Assertion Failed! String manipulation using pointer arithmetic

EDIT: Pastebin links to the entirety of the code at the bottom
for my CS215 course, I was given a class called String215 which is a basic string class to help in the understanding of dynamic memory allocation and pointer arithmetic with char arrays.
The class was given to me in a very basic skeleton form with prototypes but no implementations, along with a test function to test my implementations. I CAN NOT use any C String functions in this assignment.
The part of the program which is troubling is the append function, which just appends a parameter string215 object to the end of the current string215 object.
// Add a suffix to the end of this string. Allocates and frees memory.
void string215::append(const string215 &suffix)
{
char *output = new char[str_len(data)+suffix.length()+1];
for(int x = 0; x < str_len(data); x++) {
*output = *data;
output++;
data++;
}
for(int x = 0; x < suffix.length(); x++) {
*output = suffix.getchar(x);
output++;
}
*output = '\0';
output -= (str_len(data)+suffix.length()+1);
delete[] data;
data = output;
}
This portion of the code is tested in the 13th test of the test function as shown here:
string215 str("testing");
...
// Test 13: test that append works in a simple case.
curr_test++;
string215 suffix("123");
str.append(suffix);
if (strcmp(str.c_str(), "testing123") != 0) {
cerr << "Test " << curr_test << " failed." << endl;
failed++;
}
Here is the description of the append class:
Add the suffix to the end of this string. Allocates a new, larger, array; copies the old contents, followed by the suffix, to the new array; then frees the old array and updates the pointer to the new one.
My program aborts at the very end of the append function execution with the error message:
Debug Assertion Failed!
Program: [Source path]\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
Abort || Retry || Ignore
I'm fairly certain it has something to do with my very poor memory management. I know it's not a lot to go on, but I've been struggling with this for hours on end and can't seem to figure it out.
Here's a pastebin of the .cpp and .h file for this program
string215.cpp: http://pastebin.com/Xh2SvDKJ
string215.h: http://pastebin.com/JfAJDEVN
Any help at all is greatly appreciated!
Thanks,
RAW-BERRY
You are changing data pointer before delete[]. You need to delete[] exactly the same value you got from new[].
Also, you are incrementing output pointer str_len(data)+suffix.length() times, and you take it back by str_len(data) + suffix.length() + 1.
I would use separate variables for iteration to solve these problems.
You increment output exactly str_len(data) + suffix.length() times. Note that you don't increment output after *output = '\0';.
So to go back to the start, you should use:
output -= (str_len(data) + suffix.length());
By the way, some of the code is not very efficient. For example, getchar uses a loop instead of simply returning data[index]. You use getchar in append, which means that the performance isn't great.
EDIT: As zch says, you use delete[] data after modifying data, but note that even before that you use str_len(data) after modifying data (when deciding how many bytes to go skip back), so the calculation is wrong (and my suggestion above is also wrong, because str_len(data) is now zero).
So I think your problem is with the line
for(int x = 0; x < str_len(data); x++) {
Notice that the size of 'data' is changing at each iteration of the loop. As you increment 'x', you are decreasing the length of 'data'. Suppose 'data' is a string holding "hello": in the first iteration of the loop x=0 and str_len(data)=5; in the second iteration x=1 and str_len(data)=4. Thus the for loop executes half as many times as you need it to and 'data' does not end up pointing to the end of the data string

Convert i of For Loop to QString

Edited-
Here's where I'm getting thrown down:
for(int i=0, a=bugModel->rowCount(); i<a; i++){
qDebug() << i;
QString *BugName = new QString(QString::number(i));
setting.beginGroup(BugName->toAscii());
bugModel->setData(bugModel->index(i,0), setting.value("theBugName", "A Bug!").toString());
setting.endGroup();
delete BugName;
}
I'm trying to load a Name from the setting group and set it to a list model, for which the name will equal to i. But everytime I load the model, the information of the group '0' only shows up, because i is 0 in here. For example:
I have two setting group named '0' and '1'. I want the for loop to run 2 times so that it loads the value from these groups and set it in the QListView. But I tested it out and everytime it loads only the value of the '0' group, and when I change it to for(int i=1..) it loads the value of the group '1'.
To fix the first case, you can (*BugName) = QString::number(i) or BugName->setNum(i);, but the bigger question is what are you trying to achieve and how do you check if it stays zero? What do you expect to change? Maybe give more context?
Based on the weird use of 'a', I'm guessing that there's a bunch of other code that you didn't post. As it stands now, the loop is equivalent to for (int i = 0; i < 2; ++i), and thus only iterates through i=0 and i=1. On the first pass, it creates a new QString, assigns the address to the bugname pointer, then attempts (incorrectly) to assign a string to it. You can change the second line to *BugName = QString::number(i); and it should work. Even better, you can use one of the QString constructors and change the first line to QString* BugName = new QString(QString::number(i)) and eliminate the second line altogether.
Now for the second problem, your memory leak. After the first pass, the loop resets and you create a second qstring, overwritting bugname with the new address. Unfortunately, this orphans the first qstring you made causing a leak. Add the line delete BugName; just before the end of the loop to fix. If you're actually trying to create an array of 'BugNames' for use after the loop, you probably want to use an array instead: Put QString BugNames[2] before the loop, then use the loop to iterate through and initialize them individually via BugNames[i] = QString::number[i]. Since arrays are automatic variables, you won't need the delete part for this latter case.
Edit
Looking at your revised code, I would do it this way (old way still valid though):
for(int i=0; i < bugModel->rowCount(); i++){
qDebug() << i;
QString BugName = QString::number(i);
setting.beginGroup(BugName.toAscii());
bugModel->setData(bugModel->index(i,0), setting.value("theBugName", "A Bug!").toString());
setting.endGroup();
}
Note that your use of 'a' is redundant, since it (and indeed the loop itself) would likely be removed by the compiler. Now that I see what you're doing, I'd ditch the pointer-strings altogether and just go with a single automatic variable. As for the problem of it not working, qDebug should be outputting "0 1", yes? You can try qDebug() << BugName; after the ::number assignment, but I suspect that will output "0 1" as well. That would mean that your real issue lies somewhere in the begin/endGroup() functions, and not in this loop. If the argument to beginGroup gets assigned to something static, you might be overwritting a value with the second pass.