I have a 15x20 array, and I want to change the value of each entry, then cout them all.
char map[15][80];
Here is my code to cout all entries.
for (int a=0;a<=15;a++) {
for (int b=0;b<=80;b++) {
map[a][b] = 'a';
cout << map[a][b]; } }
The problem occurs if I place the alphabet into an array, it will print a certain letter more than once.
char map[15][80];
Your for loops are reading one element past the array you allocated.
for (int a=0;a<=15;a++)
^^^^^
for (int b=0;b<=80;b++)
^^^^^
Valid indexes are only from 0 to 14 in first case &
0 to 79 in second case.
Note that C/C++ do not do array bounds checking for you, So you have to be careful about not writing beyond the bounds of the array, if you do so what you get is Undefined Behavior, which means your C/C++ program is not valid anymore.
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 am trying to make an own simple string implementation in C++. My implementation is not \0 delimited, but uses the first element in my character array (the data structure I have chosen to implement the string) as the length of the string.
In essence, I have this as my data structure: typedef char * arrayString; and I have got the following as the implementation of some primal string manipulating routines:
#include "stdafx.h"
#include <iostream>
#include "new_string.h"
// Our string implementation will store the
// length of the string in the first byte of
// the string.
int getLength(const arrayString &s1) {
return s1[0] - '0';
}
void append_str(arrayString &s, char c) {
int length = getLength(s); // get the length of our current string
length++; // account for the new character
arrayString newString = new char[length]; // create a new heap allocated string
newString[0] = length;
// fill the string with the old contents
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
// append the new character
newString[length - 1] = c;
delete[] s; // prevent a memory leak
s = newString;
}
void display(const arrayString &s1) {
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
}
void appendTest() {
arrayString a = new char[5];
a[0] = '5'; a[1] = 'f'; a[2] = 'o'; a[3] = 't'; a[4] = 'i';
append_str(a, 's');
display(a);
}
My issue is with the implementation of my function getLength(). I have tried to debug my program inside Visual Studio, and all seems nice and well in the beginning.
The first time getLength() is called, inside the append_str() function, it returns the correct value for the string length (5). When it get's called inside the display(), my own custom string displaying function (to prevent a bug with std::cout), it reads the value (6) correctly, but returns -42? What's going on?
NOTES
Ignore my comments in the code. It's purely educational and it's just me trying to see what level of commenting improves the code and what level reduces its quality.
In get_length(), I had to do first_element - '0' because otherwise, the function would return the ascii value of the arithmetic value inside. For instance, for decimal 6, it returned 54.
This is an educational endeavour, so if you see anything else worth commenting on, or fixing, by all means, let me know.
Since you are getting the length as return s1[0] - '0'; in getLength() you should set then length as newString[0] = length + '0'; instead of newString[0] = length;
As a side why are you storing the size of the string in the array? why not have some sort of integer member that you store the size in. A couple of bytes really isn't going to hurt and now you have a string that can be more than 256 characters long.
You are accessing your array out of bounds at couple of places.
In append_str
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
In the example you presented, the starting string is "5foti" -- without the terminating null character. The maximum valid index is 4. In the above function, length has already been set to 6 and you are accessing s[5].
This can be fixed by changing the conditional in the for statement to counter < length-1;
And in display.
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
Here again, you are accessing the array out of bounds by using counter <= max in the loop.
This can be fixed by changing the conditional in the for statement to counter < max;
Here are some improvements, that should also cover your question:
Instead of a typedef, define a class for your string. The class should have an int for the length and a char* for the string data itself.
Use operator overloads in your class "string" so you can append them with + etc.
The - '0' gives me pain. You subtract the ASCII value of 42 from the length, but you do not add it as a character. Also, the length can be 127 at maximum, because char goes from -128 to +127. See point #1.
append_str changes the pointer of your object. That's very bad practice!
Ok, thank you everyone for helping me out.
The problem appeared to be inside the appendTest() function, where I was storing in the first element of the array the character code for the value I wanted to have as a size (i.e storing '5' instead of just 5). It seems that I didn't edit previous code that I had correctly, and that's what caused me the issues.
As an aside to what many of you are asking, why am I not using classes or better design, it's because I want to implement a basic string structure having many constraints, such as no classes, etc. I basically want to use only arrays, and the most I am affording myself is to make them dynamically allocated, i.e resizable.
I have been writing some code to create a byte array I will be sending over a socket to another process. However noticed some really odd behavior regarding my byte[].
The cout at the end prints out 99, however looking at my code, I couldn't find where the value is being set. I create a char array of size sendingSize which is a constant. I don't set the value 307200* 3 so I don't understand how it prints out with a value...
char tosend[sendingSize];
//Send over the frame
for(int i = 0; i < 307200; i++)
{
tosend[i * 3] = (byte)imCopy[i/640][i%640].red;
tosend[i * 3+1] = (byte)imCopy[i/640][i%640].green;
tosend[i * 3+2] = (byte)imCopy[i/640][i%640].blue;
}
char *bytePointer = tosend;
cout<<(int)tosend[307200* 3]<<endl;
Your code does not write any value into index 307200*3 (because the highest index your for loop reaches is 307199). So you are reading some byte from memory beyond the declared size of your array. This is undefined behaviour and anything could happen.
Some other programming languages (such as Java) do automatic range checking on arrays and would throw an exception in this case. In C++, you are expected to do the right thing and the compiler doesn't generate range checking code for you.
Having some issues with one small function I'm working on for a homework assignment.
I have a static array size of 20 (shelfSize), however, I only need to use a max of 10 elements. So I don't have to worry about out of bounds etc (the entire array of 20 is initialized to 0).
What I am looking to do is insert an integer, booknum, into an element of an array it receives as input.
This my current logic:
void insert_at(int booknum, int element){
for(int i=element+1; i < shelfSize; i++)
bookshelf[i+1]=bookshelf[i]
bookshelf[element]=booknum;
}
so let's say I have the this array:
[5,4,3,1,7]
I want to insert an 8 at element 1 and have the array turn to:
[5,8,4,3,1,7]
Technically, everything after the final element 7 is a 0, however, I have a separate print function that only prints up to a certain element.
No matter how many times I take some pencil and paper and manually write out my logic, I can't get this to work.
Any help would be appreciated, thanks.
You should start from the end of the array, this should word for you:
void insert_at(int booknum, int element)
{
for (int i = shelfsize-1;i>element;i--)
bookshelf[i] = bookshelf[i-1];
bookshelf[element] = booknum;
}
Also I recommend that you get used to handling illegal values, for example, what if a user entered 21?
The optimized code would be:
bool insert_at(int booknum, int element)
{
if (element>=shelfsize-1)
return false;
for (int i = shelfsize-2;i>element;i--)
bookshelf[i] = bookshelf[i-1];
bookshelf[element] = booknum;
return true;
}
If your example is correct, then you're assuming 1-based indices instead of 0-based. Use the following instead:
void insert_at(int booknum, int element){
for(int i=element; i < shelfSize; i++)
bookshelf[i]=bookshelf[i-1];
bookshelf[element-1]=booknum;
}
However, I would prefer you just use the same code, and change "at element 2" in your example to "at element 1". Always remember C++ arrays are 0-based.
That being said, please tell your professor that this is why vectors (and other standard containers) were made, and that C++ arrays are evil.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1
Just noticed, you are copying up, this means your function does this:
[5,4,3,1,7]
--^
[5,4,4,1,7]
--^
[5,4,4,4,7]
--^
[5,4,4,4,4]
--^
[5,4,4,4,4,4]
For moving values in an array, you always want to copy in the opposite direction to which you are moving, so to move up, you want to copy each item up from the top down:
[5,4,3,1,7]
--^
[5,4,3,1,7,7]
--^
[5,4,3,1,1,7]
--^
[5,4,3,3,1,7]
--^
[5,4,4,3,1,7]
And then you can overwrite the index you freed up.
My task consists of two parts. First I have to create globbal char array of 100 elements, and insert some text to it using cin. Afterwards calculate amount of chars, and create dedicated array with the length of the inputted text. I was thinking about following solution :
char[100]inputData;
int main()
{
cin >> inputData >> endl;
int length=0;
for(int i=0; i<100; i++)
{
while(inputData[i] == "\0")
{
++count;
}
}
char c = new char[count];
Am I thinking good ?
Second part of the task is to introduce in the first program dynamically created array of pointers to all inserted words. Adding a new word should print all the previous words and if there is no space for next words, size of the inputData array should be increased twice. And to be honest this is a bit too much for me. How I can create pointers to words specifically ? And how can I increase the size of global array without loosing its content ? With some temporary array ?
Regardless of the rest of your question, you appear to have some incorrect ideas about while loops. Let's look at this code.
for(int i=0; i<100; i++) {
while(inputData[i] == "\0") {
++count;
}
}
First, "\0" is not the NUL character. It is a pointer to a string containing only the terminating NUL byte. You want '\0' instead. Assuming this change, there are still problems. Let's work through what will happen:
How does a while loop work? It executes the body repeatedly, as long as the condition is true.
When does a while loop finish? When the condition is finally made false by executing the body.
What's the condition of your loop? inputData[i] == '\0', after correction.
What's the body? ++count.
Can ++count ever change the value of the condition? No, because it doesn't change i.
So, if inputData[i] is not the NUL byte, the while loop never executes.
But, if inputData[i] is the NUL byte, the while loop executes forever.
Assuming you've read a proper string into inputData, then at some point inputData[i] will be NUL, and you'll have an infinite loop.
To count the length of a standard C string, just do this
count = strlen(inputData);
If for some reason you really have to write a loop, then the following works:
int len = 0,
while (inputData[len] != '\0') {
len++;
}
After the loop, len holds the length of the string.
#include <iostream>
#include <string>
int main()
{
std::string input;
std::getline(std::cin, input);
}
Global arrays can't have the size changed dynamically unless they are a pointer to an array, in which case you can erase them and reallocate them.
Perhaps what you're after is an automatically resizing array, like a std::vector. You can see how many letters you have in the array by calling size() on the vector, and you can increase the size of the array by calling resize().
While not the most elegant solution, it might be a bit easier to use for the moment.