Using Base + Offset to grab 4 chars as an int

I have a char array called 'mem' sized to 100 Bytes. I'm trying to use "base address + offset" to access different parts of my simulated memory. I know that "mem + 4" is what is needed for inputting integers into memory and a char is "mem + 1".

What I'm wanting to do is grab four chars as a single number and utilizing base + offset, insert it somewhere else into mem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  int j=10, i=3, k=7, a, *ii, *jj;	// int, int, pointer to int
	char c='a', *cc;		// char, pointer to char

	char mem[100];
	
	ii = (int*)(mem + 4);
	*ii = j;
	ii = (int*)(mem + 8);
	*ii = i;

	cc = mem + 12;
	*cc = 'a'; 
	cc = mem + 13;
	*cc = 'b';
	cc = mem + 14;
	*cc = 'c';
	cc = mem + 15;
	*cc = 'd';
	
	ii = (int*)(mem + 4);
	
	cout << "*ii: " << *ii << endl;  // Prints 10
	cc = mem + 12;
	cout << "Base + 12: " << *cc << endl;	// a
	cc = mem + 13;
	cout << "Base + 13: " << *cc << endl;	// b
	cc = mem + 14;
	cout << "Base + 14: " << *cc << endl;	// c
	cc = mem + 15;
	cout << "Base + 15: " << *cc << endl;	// d
	
	cc = mem + 50;
	ii = (int*)(mem + 12);

        jj = (int*)(mem + 50);
	jj = ii;
	
	cout << "*ii: " << *ii <<endl;          // 
	cc = (char*)jj;
	cout << "Base + 50: " << *cc << endl;	// a
	cc = mem + 51;
	cout << "Base + 51: " << *cc << endl;	// b; actually getting ||-
	cc = mem + 52;
	cout << "Base + 52: " << *cc << endl;	// c; actually getting ||-
	cc = mem + 53;
	cout << "Base + 53: " << *cc << endl;	// d; actually getting ||- 


So I essentially want to grab mem + 12 through mem + 15 as an integer value and utilizing the above techniques (base + offset, casting, and pointers) move/copy it into another location in mem.
unsigned char data[100];
int *imanint = (int*)(&data[23]); //alternately (int*)(data+23)
imanint[0] = 123456;

and you can move it as an integer or as a char chunk.
memcpy(somewhereelse, data+23, sizeof(int));
or cleaner
int somewhereelse = *imanint;

if you want a 4 byte int, say so explicitly so your code is portable.
use int32_t or similar size-enforced typedefs from c99 or whatever flavor. If you use int, it could be 32, 64, or 128 bits currently (this covers MOST systems in play today) and 256 or even 512 in 10 years.

this looks pretty much like what you did, what is not working? The only 2 things that come to mind are 1) signed char can be troubling when playing with 'bytes' and 2) int size may not be what you thought it was.
Last edited on
1
2
3
4
5
6
7
8
        cc = (char*)jj;
	cout << "Base + 50: " << *cc << endl;	// a
	cc = mem + 51;
	cout << "Base + 51: " << *cc << endl;	// b; actually getting ||-
	cc = mem + 52;
	cout << "Base + 52: " << *cc << endl;	// c; actually getting ||-
	cc = mem + 53;
	cout << "Base + 53: " << *cc << endl;	// d; actually getting ||- 


It's possible that I don't quite understand this part of it quite yet and that could be my issue. Essentially I want Base+50 through Base+53 to be 'a','b','c','d' (like it is for Base + 12 through Base + 15) but that appears to be accomplished with your explanation of memcpy, unless I'm wrong.
I am not sure what you don't see, so a quick example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

int main( int argc, char **argv)
    {		
	    char mem[100] = {0};
		strcpy(mem+50,"abcd"); //mem 50-54 assigned (54 is zero terminal, harmless here)
		cout << mem+50 << endl; //abcd
		//cout << sizeof(int) << endl; //I got 4 on my test box, just check this on yours
		int* ip = (int*)(mem+50);//1684234849  looking at mem 50-53 as an integer
		cout <<  *ip << endl;  
		int* ip2 = (int*)(mem); //any location other than 50-53 will do here
		*ip2 = 1684234849; //the string abcd as an integer. 
		cout << mem << endl; //mem[0],1,2,3 (a,b,c,d) (zero terminated via {0} initialize)		
		return 0;
	}

memcpy moves raw bytes from one place to another. It may be what you seek to do. (?). It is good for moving arrays and simple C-style structs (without pointer data inside) but it is C and 'a wee bit unsafe' for the novice :) It *sounds* like this is all you need and what you are trying to replicate. In that case, read the documentation on memcpy and memmove.

it would really help about now to know what exactly you want to do. You can usually find a way in C++ to get your data in byte format (this is powerful at times) and shovel it around as you see fit. The question is, to what purpose; it is easy to make bad mistakes doing this kind of work and the only places I use it are serialization (think, send data over network or to a file) and if working embedded, you may need to hand roll some memory management.

if you just want to move blocks of 4 bytes around, you can do that as int32 as demonstrated. If you want to move a lot of bytes around, memcpy is really good at what it does.
Last edited on
Didn't I answer this already?

1
2
3
4
5
6
7
8
9
10
11
int read_int(const void *mem, int offset){
    int ret;
    memcpy(&ret, (char*)mem + offset, sizeof(ret));
    return ret;
}

//...

char mem[100];
std::cout << read_int(mem, 4) << std::endl;
std::cout << read_int(mem, 8) << std::endl;
Topic archived. No new replies allowed.