memset sets random values [duplicate] - c++

This question already has answers here:
Why does "memset(arr, -1, sizeof(arr)/sizeof(int))" not clear an integer array to -1?
(6 answers)
Closed 8 years ago.
Here is the code:
#include <iostream>
#include <cstring>
int main()
{
int win[11];
std::memset(win, 1, sizeof(win));
for (int i = 0; i < 11; ++i)
std::cout << win[i] << ' ';
std::cout << std::endl;
return 0;
}
I think there is no logic flaw here? But instead of getting a string of 1 printed, I got 16843009.
If I change the memset to std::memset(win, 0, sizeof(win)). Then everything is as expected. The content of win is all zeros.
Am I missing something here?
I'm using g++ 4.7.3 on Ubuntu 13.04.
Sorry for this duplicated question.
Here is the answer. Thanks
Why does "memset(arr, -1, sizeof(arr)/sizeof(int))" not clear an integer array to -1?

ints are usually four bytes long. But memset sets the value of individual bytes, so you're setting each value to 0x01010101, which just so happens to equal 16843009.

The memset function writes over memory without understanding its structure in any way. If you write a bunch of random 1's all over an accounting report, will that make the report show that the company has spent $1? I don't think so. Maybe it will show 111111 dollars. Maybe not. Who knows.
To modify an object's value intelligently, you have to understand its structure. The memset function does not understand the structure of win and just scribbles 1 all over its bytes. What that means, memset does not know or care.

Related

Why can array cells exceed array length [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 7 years ago.
While debugging I found an error with an int array of 0. In a test document I messed around with array with more cell input than their length.
int array[0];
for(int i = 0; i < 10; i++)
array[i] = i;
for(int i = 0; i < 10; i++)
cout << array[i];
After I compiled and ran the program I got
0123456789
Then I received the message "test.exe has stopped working". I expected both of these, but what I am confused about is why the compiler lets me create an array of 0, and why the program doesn't crash until the very end of the program. I expected the program to crash once I exceeded the array length.
Can someone explain?
The compiler should have at least warned you about a zero size array - if it didn't .. consider changing compiler.
Remember that an array is just a bit of memory just like any other. In your example the array is probably stored on the stack and so writing off the end of it may not cause much of a problem until your function exits. At that point you may find you have written some text over the return address and you get an exception. Writing off the end of arrays are a common cause of bugs in C/C++ - just be thankful you got an error with this one and it didn't just overwrite some other unrelated data.

memcmp multiple BYTEs, not finding address [duplicate]

This question already has an answer here:
SizeOfImage member causing program crash
(1 answer)
Closed 9 years ago.
Im trying to memcmp multiple BYTE's from ASM Instructions but my scanner keeps coming up with nothing. The returning value from my function indicates that the BYTEs are not being found.
Called with
const BYTE Pattern[] = {0x33,0xC0,0xF2,0xAE};
DWORD Address = FindPattern(Pattern,sizeof(Pattern));
Function(Shortend)
DWORD FindPattern(const BYTE* Pattern,SIZE_T PatternSize)
{
...
for(int i = 0;i < (ModuleSize - PatternSize);i++)
{
if(memcmp((void*)(ModuleBase + i),Pattern,PatternSize) == 0)
return ModuleBase + i;
}
return 0;
}
As I replied in your previous similar question, you code worked perfectly fine when i ran it. I tested it against the previous FindPattern function i was using, and both returned the same exact results.
Make sure you have the correct pattern. Its not your function that is failing, its simply not finding what you are looking for.

Value Printed changes based on instructions that come after it

I appear to have coded a class that travels backwards in time. Allow me to explain:
I have a function, OrthogonalCamera::project(), that sets a matrix to a certain value. I then print out the value of that matrix, as such.
cam.project();
std::cout << "My Projection Matrix: " << std::endl << ProjectionMatrix::getMatrix() << std::endl;
cam.project() pushes a matrix onto ProjectionMatrix's stack (I am using the std::stack container), and ProjectionMatrix::getMatrix() just returns the stack's top element. If I run just this code, I get the following output:
2 0 0 0
0 7.7957 0 0
0 0 -0.001 0
-1 -1 -0.998 1
But if I run the code with these to lines after the std::cout call
float *foo = new float[16];
Mat4 fooMatrix = foo;
Then I get this output:
2 0 0 0
0 -2 0 0
0 0 -0.001 0
-1 1 -0.998 1
My question is the following: what could I possibly be doing such that code executed after I print a value changes the value being printed?
Some of the functions I'm using:
static void load(Mat4 &set)
{
if(ProjectionMatrix::matrices.size() > 0)
ProjectionMatrix::matrices.pop();
ProjectionMatrix::matrices.push(set);
}
static Mat4 &getMatrix()
{
return ProjectionMatrix::matrices.top();
}
and
void OrthogonalCamera::project()
{
Mat4 orthProjection = { { 2.0f / (this->r - this->l), 0, 0, -1 * ((this->r + this->l) / (this->r - this->l)) },
{ 0, 2.0f / (this->t - this->b), 0, -1 * ((this->t + this->b) / (this->t - this->b)) },
{ 0, 0, -2.0f / (this->farClip - this->nearClip), -1 * ((this->farClip + this->nearClip) / (this->farClip - this->nearClip)) },
{ 0, 0, 0, 1 } }; //this is apparently the projection matrix for an orthographic projection.
orthProjection = orthProjection.transpose();
ProjectionMatrix::load(orthProjection);
}
EDIT: whoever formatted my code, thank you. I'm not really too good with the formatting here, and it looks much nicer now :)
FURTHER EDIT: I have verified that the initialization of fooMatrix is running after I call std::cout.
UPTEENTH EDIT: Here is the function that initializes fooMatrix:
typedef Matrix<float, 4, 4> Mat4;
template<typename T, unsigned int rows, unsigned int cols>
Matrix<T, rows, cols>::Matrix(T *set)
{
this->matrixData = new T*[rows];
for (unsigned int i = 0; i < rows; i++)
{
this->matrixData[i] = new T[cols];
}
unsigned int counter = 0; //because I was too lazy to use set[(i * cols) + j]
for (unsigned int i = 0; i < rows; i++)
{
for (unsigned int j = 0; j < cols; j++)
{
this->matrixData[i][j] = set[counter];
counter++;
}
}
}
g64th EDIT: This isn't just an output problem. I actually have to use the value of the matrix elsewhere, and it's value aligns with the described behaviours (whether or not I print it).
TREE 3rd EDIT: Running it through the debugger gave me a yet again different value:
-7.559 0 0 0
0 -2 0 0
0 0 -0.001 0
1 1 -0.998 1
a(g64, g64)th EDIT: the problem does not exist compiling on linux. Just on Windows with MinGW. Could it be a compiler bug? That would make me sad.
FINAL EDIT: It works now. I don't know what I did, but it works. I've made sure I was using an up-to-date build that didn't have the code that ensures causality still functions, and it works. Thank you for helping me figure this out, stackoverflow community. As always you've been helpful and tolerant of my slowness. I'll by hypervigilant for any undefined behaviours or pointer screw-ups that can cause this unpredictability.
You're not writing your program instruction by instruction. You are describing its behavior to a C++ compiler, which then tries to express the same in machine code.
The compiler is allowed to reorder your code, as long as the observable behavior does not change.
In other words, the compiler is almost certainly reordering your code. So why does the observable behavior change?
Because your code exhibits undefined behavior.
Again, you are writing C++ code. C++ is a standard, a specification saying what the "meaning" of your code is. You're working under a contract that "As long as I, the programmer, write code that can be interpreted according to the C++ standard, then you, the compiler, will generate an executable whose behavior matches that of my source code".
If your code does anything not specified in this standard, then you have violated this contract. You have fed the compiler code whose behavior can not be interpreted according to the C++ standard. And then all bets are off. The compiler trusted you. It believed that you would fulfill the contract. It analyzed your code and generated an executable based on the assumption that you would write code that had a well-defined meaning. You did not, so the compiler was working under a false assumption. And then anything it builds on top of that assumption is also invalid.
Garbage in, garbage out. :)
Sadly, there's no easy way to pinpoint the error. You can carefully study ever piece of your code, or you can try stepping through the offending code in the debugger. Or break into the debugger at the point where the "wrong" value is seen, and study the disassembly and how you got there.
It's a pain, but that's undefined behavior for you. :)
Static analysis tools (Valgrind on Linux, and depending on your version of Visual Studio, the /analyze switch may or may not be available. Clang has a similar option built in) may help
What is your compiler? If you are compiling with gcc, try turning on thorough and verbose warnings. If you are using Visual Studio, set your warnings to /W4 and treat all warnings as errors.
Once you have done that and can still compile, if the bug still exists, then run the program through Valgrind. It is likely that at some point in your program, at an earlier point, you read past the end of some array and then write something. That something you write is overwriting what you're trying to print. Therefore, when you put more things on the stack, reading past the end of some array will put you in a completely different location in memory, so you are instead overwriting something else. Valgrind was made to catch stuff like that.

Pointer to lowest address in memory [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Detecting endianness programmatically in a C++ program
I'm trying to check if I'm running a little or big endian OS.
int main()
{
int i = 1;
unsigned char b = i;
char *c = reinterpret_cast<char*>(&i); // line 5
cout << "Processor identified as: " << endl;
if (*c == b)
cout << "Little endian" << endl;
else
cout << "Big endian" << endl;
}
I'm not sure if casting an int* to char* pointer in line 5 is guaranteed to return a lowest address. Am I doing it right?
It might give you the bottom address of the call stack (of the main thread).
But heap addresses may compare lower (or upper) to that address.
Also, stack growth direction is orthogonoal to endianess.
The C++ standard does not place any restrictions on the byte content of an integer. You may find some systems that are neither little nor big endian - eg, the PDP-11 used a format in which 0x0A0B0C0D was stored as 0B 0A 0D 0C. It's also allowed for there not to be any 0x01 byte at all in the representation for 1.
As for whether the cast will return the lowest byte in the int, it will. However, again, the content of this byte is not well-defined by the C++ specification.
Your char will have the same address as your int, which will be the lowest address of any byte in the int. In don't know if this is actually guaranteed, but it's true on every system I've ever used.

how to cast an array of char into a single integer number?

i'm trying to read contents of PNG file.
As you may know, all data is written in a 4-byte manner in png files, both text and numbers. so if we have number 35234 it is save in this way:
[1000][1001][1010][0010].
but sometimes numbers are shorter, so the first bytes are zero, and when I read the array and cast it from char* to integer I get wrong number. for example [0000] [0000] [0001] [1011]
sometimes numbers are misinterpreted as negative numbers and simetimes as zero!
let me give you an intuitive example:
char s_num[4] = {120, 80, 40, 1};
int t_num = 0;
t_num = int(s_num);
I wish I could explain my problem well!
how can i cast such arrays into a single integer value?
ok ok ok, let me change my code to explain it better:
char s_num[4] = {0, 0, 0, 13};
int t_num;
t_num = *((int*) s_num);
cout << "t_num: " << t_num << endl;
here we have to get 13 as the result, ok?
but again with this new solution the answer is wrong, you can test on your computers!
i get this number:218103808 which is definitely wrong!
You cast (char*) to (int). What you should do is cast to pointer to integer, i.e.
t_num = *((int*) s_num));
But really you should extract your code into it's own function and make sure that:
endianness is correct
sizeof(int) == 4
Use C++ casts (i.e. static, dynamic, const, reinterpret)
Assuming a little-endian machine with a 32-bit integer, you can do:
char s_num[4] = {0xAF, 0x50, 0x28, 0x1};
int t_num = *((int*)s_num);
To break it into steps:
s_num is an array, which can be interpreted as a pointer to its first element (char* here)
Cast s_num to int* because of (1) - it's OK to cast pointers
Access the integer pointed to by the cast pointer (dereference)
To have 0xAF as the low byte of the integer. Fuller example (C code):
#include <stdio.h>
int main()
{
char s_num[4] = {0xAF, 0x50, 0x28, 0x1};
int t_num = *((int*)s_num);
printf("%x\n", t_num);
return 0;
}
Prints:
12850af
As expected.
Note that this method isn't too portable, as it assumes endianness and integer size. If you have a simple task to perform on a single machine you may get away with it, but for something production quality you'll have to take portability into account.
Also, in C++ code it would be better to use reinterpret_cast instead of the C-style cast.
I find using the std bitset the most explicit way of doing conversions (In particular debugging.)
The following perhaps is not what you want in your final code (too verbose maybe) - but I find it great for trying to understand exactly what is going on.
http://www.cplusplus.com/reference/stl/bitset/
#include <bitset>
#include <iostream>
#include <string>
int
main (int ac, char **av)
{
char s_num[4] = {120, 80, 40, 1};
std::bitset<8> zeroth = s_num[0];
std::bitset<8> first = s_num[1];
std::bitset<8> second = s_num[2];
std::bitset<8> third = s_num[3];
std::bitset<32> combo;
for(size_t i=0;i<8;++i){
combo[i] = zeroth[i];
combo[i+8] = first[i];
combo[i+16] = second[i];
combo[i+24] = third[i];
}
for(size_t i = 0; i<32; ++i)
{
std::cout<<"bits ["<<i<<"] ="<<combo.test(i)<<std::endl;
}
std::cout<<"int = "<<combo.to_ulong()<<std::endl;
}
Axel's answer violates the strict aliasing rule, at least since C++14. So I post this answer for future users.
Apart from endianness and size issues, a safe way is to use std::memcpy, i.e.
unsigned char s_num[4] = {13, 0, 0, 0};
// ^^^^^^^^ // ^^ fix endianness issue
// use unsigned char to avoid potential issues caused by sign bit
int t_num;
std::memcpy(&t_num, s_num, 4);
EDIT: it seems that you don't want to sum the numbers after all. Leaving this answer here for posterity, but it likely doesn't answer the question you want to ask.
You want to sum the values up, so use std::accumulate:
#include <numeric>
#include <iostream>
int main(void) {
char s_num[4] = {120,80,40,1};
std::cout << std::accumulate(s_num, s_num+4,0) << std::endl;
return 0;
}
Produces output:
pgp#axel02:~/tmp$ g++ -ansi -pedantic -W -Wall foo.cpp -ofoo
pgp#axel02:~/tmp$ ./foo
241
Did you know that int's in C++ overflow after the 32767'th value? That would explain your negative number for 35234.
The solution is to use a data type that can handle the larger values. See the Integer Overflow article for more information:
http://en.wikipedia.org/wiki/Integer_overflow
UPDATE: I wrote this not thinking that we all live in the modern world where 32 bit and 64 bit machines exist and flourish!! The overflow for int's is in fact much much larger than my original statement.
Conversion is done good, because you aren't summing up these values but assign them as one value. If you want to sum them you have to do it manualy:
int i;
for (i = 0; i<4; ++i)
t_num += s_num[i];