Odd behaviour with byte[] C++ - c++

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.

Related

Put an array in the end of another array C++

Normally it's a question about a buffer with a null-terminated string, but we can extrapolate it to a general case.
I have a big array of a fixed length, let's say 10:
char outputArray[10] = {'-','-','-','-','-','-','-','-','-','-'};
And I have some other (Edited: smaller) array (in my case it's a char buffer with null terminator) with a variable length. Let's say it's a buffer of 6 elements, but the actual length is indicated by another variable.
char inputArray[10] = {'h','i','/0',...some other values, i'm not interested in};
int arrLength = 2; // For my task it means a strlen(inputArray);
How to put a small array at the end of a big array, to get this:
outputArray = {'-','-','-','-','-','-','-','-','h','i'} // the null terminator isn't important, it's not about the strings, it's about arrays.
Constraints:
I can't use std, so only "native" solutions (it's for Arduino)
C++11
Code should be memory and time efficient (some elegant algorithm without too much loops and too much temporary variables or calculations please)
Thank you in advance
Edited:
Thank to #ThomasWeller for an answer. I have a small precision though. What if I need to clean all the elements before the inserted array?
For example I had some garbage
{'a','k','$','-','n','"','4','i','*','%'};
And I need to get
{'-','-','-','-','-','-','-','-','h','i'};
Do I need 2 loops? First to reset an array and the second one to set the actual result?
It can be done with a single for loop and a single variable:
for (char i=0; i<arrLength; i++)
{
outputArray[10-arrLength+i] = inputArray[i];
}
If you make arrLength a char instead of an int, this will even save you 2 bytes of memory ;-)
Use memset() to set all memory to an initial value and then memcpy() the contents at the end:
char output[10];
char input[10] = "hi\0------";
char arrLength = 2;
void setup() {
memset(output, '-', 10); // "----------"
memcpy(output+10-arrLength, input, arrLength);
Serial.begin(9600);
Serial.write(output, 10);
}
void loop() { }

c_str() is only reading half of my string, why? How can I fix this? Is it a byte issue?

I am writing a client program and server program. On the server program, in order to write the result back to the client, I have to convert the string to const char* to put it in a const void* variable to use the write() function. The string itself is outputting the correct result when I checked, but when I use the c_str() function on the string, it is only outputting up until the first variable in the string. I am providing some code for reference (not sure if this is making any sense).
I have already tried all sorts of different ways to adjust the string, but nothing has worked yet.
Here are how the variables have been declared:
string final;
const void * fnlPrice;
carTable* table = new carTable[fileLength];
Here is the struct for the table:
struct carTable
{
string mm; // make and model
string hPrice; // high price
string lPrice; // low price
};
Here is a snipped of the code with the issue, starting with updating the string variable, final, with text as well as the resulting string variables:
final = "The high price for that car is $" + table[a].hPrice + "\nThe low
price for that car is $" + table[a].lPrice;;
if(found = true)
{
fnlPrice = final.c_str();
n = write(newsockfd,fnlPrice, 200);
if (n < 0)
{
error("ERROR writing to socket");
}
}
else
{
n = write(newsockfd, "That make and model is not in
the database. \n", 100);
if (n < 0)
{
error("ERROR writing to socket");
}
}
Unfortunately your code does not make any sense. And that may be your major problem. You should rewrite you code end eliminate the bugs.
Switch on all compiler warnings and eliminate the warnings.
Do not use new and pointers. Never
Do not use C-Style arrays. So, something with []. Never. Use STL containers
Always initialize all variables. Always. Even if you assign an other value in the next line
Do not use magic constants like 200 (The size of the string is final.size())
If an error happens then print the error text with strerror (or a compatible function)
Make sure that your array itself and the array values are initalized
To test your function, write to socket 1 (_write(1,fnlPrice,final.size()); 1 is equal to std::cout
There is no need to use the void pointer. You can use n = _write(newsockfd, final.c_str(), final.size()); directly
If you want a detailed answer here on SO then you need to post your compiled code. I have rewritten your function and tested it. It works for me and prints the complete string. So, there is a bug in an other part of your code that we cannot not see.

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

C++ Multi Dimensional Array Problems - Entries printed more than once

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.

in visual c++, warning comes but program doesnt runs furthers, is there any way to igonre it?

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.