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));
Related
I was playing around with array and when i did this , im expecting IndexOutOfBound
however , the program still ran and gave an output 54
Where does the extra number come from ?
How to avoid these kind of indexing problem?
#include <iostream>
int main(){
int array[] = {1,2,3,4,5,6};
int total;
for(int i = 0 ; i<=7 ; i++){
total += array[i];
}
std::cout << total;
return 0;
}
C++ does not do any checking to make sure that your indices are valid for the length of your array.
Like churill notes above, indexing out of range is undefined behavior. For example, in your question, the value of array[6] is whatever is stored your memory at the location where the 6th element would have existed. In your case, this was a random value for instance from another variable.
Although rare, C++ will also let you use a negative index, with similarly undesirable results.
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);
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
I have written some code, here is a snippet of it is:
int num[8],n=0;
for (n = 0; n<8; n++)
{
char temp = binnum[n];
num[n] = atoi(&temp);
cout << num[n];
}
It doesn't gives any error, but I do get a warning. When I run it on C++, it gives Run Time Check Failure - The variable n is being used without being initialized.
After that, it doesn't run any further and the program closes. Is there any way to ignore this error? Because if I initialize n, it gives the wrong answer. For example, if answer is 101011, it will give 10101100, which is wrong.
Initialize n as #anthares pointed out and increment it at the end of the loop so your loop actually works.
int number[8];
int n = 0;
do
{
char temp = binnum[n];
number[n] = atoi(&temp);
cout << number[n];
n++;
} while (n<8);
Your main problem (after all the edits) is that atoi takes a null-terminated char array (C-style string). The address of a single char variable does not make a C-style string.
To convert a single character in range ['0'...'9'] to a corresponding number use:
number[i] = temp - '0';
possibly having checked that temp contains a digit character.
Give a value to your vairable n before using it int number [8], n=0 for example. Otherwise, it is "not defined behavior" what is the value of n and how many iterations you will do in your cycle.
Also, As it is written your loop will go forever since you never change the value of n ...
You are using n before it is assigned a value. You need to ensure that n is initialized (to 0, maybe) before you begin to reference it in your code. You do not want to ignore this error.
Try something like this:
const int count = 8;
int number[count];
for (int i=0; i < count; i++)
{
char temp = binnum[i];
number[i] = atoi(&temp);
cout << number[i];
}
what? you never assign any value to n.
and even if you will for example do int number[8],n=0; you never change n's value you you will end up with an infinite loop.
You should really initialize n (and also increment it, for that matter).
You are probably running a debug build of your application. In this case, the variable is probably always initialized with the same value. This is why you see the result you expect. It seems to behave correct purely by accident.
As soon as your application is built in release mode, n may have a different value each time the program is run and thus the output will be unpredictable.
This is what happens when you have undefined behavior in your program.
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.