I was wondering why I get these memory addresses in this simple program.
#include <stdio.h>
int main() {
char *a = "buffera";
char *b = "bufferbb";
printf("%p %p\n", a, b);
return 0;
}
Output I get is.
00403064 0040306C
Supposedly each character occupies one byte in memory (two hex numbers), then if the string a occupy 7 + 1 = 8 bytes in memory and the address of a starts at 0x00403064, then according to me it should end at 0x00403079 and not at 0x0040306B.
0043064 + 8 = 0040306C; I don't know where you get 00403079 from.
0x00403064 + 0x8 == 0x0040306C
Note that these numbers are in hexadecimal.
But either way, while these strings can't overlap, they don't need to be placed anywhere near each other in memory.
Related
I have a few questions about memory alignment in C language and how memory is allocated after forcing a variable to be aligned to a certain number of bytes using the _Alignas specifier.
This code shows in output the memory addresses of each declared variable:
#include <stdio.h>
int main(void)
{
unsigned char dx = 1;
unsigned char ca = 1;
unsigned char cx = 1;
unsigned char dz = 1;
unsigned char cb = 1;
unsigned char _Alignas(double) cz = 1;
char * p_begin = (char *) &cz;
char * p_end = (char * ) &dx + sizeof(dx);
printf("Addresses Value\n");
for (char * p = p_begin; p < p_end; p++)
{
printf("%9p %6X", p, 0xff & *p);
if (p == (char *) & dx) printf(" <- dx\n");
else if (p == (char *) & ca) printf(" <- ca\n");
else if (p == (char *) & cx) printf(" <- cx\n");
else if (p == (char *) & dz) printf(" <- dz\n");
else if (p == (char *) & cb) printf(" <- cb\n");
else if (p == (char *) & cz) printf(" <- cz\n");
else printf("\n");
}
return 0;
}
On my computer the output is as follows:
Addresses Value
28ff08 1 <- cz
28ff09 FF
28ff0a 28
28ff0b 0
28ff0c CE
28ff0d 2A
28ff0e 40
28ff0f 1 <- cb
28ff10 1 <- dz
28ff11 1 <- cx
28ff12 1 <- ca
28ff13 1 <- dx
Process returned 0 (0x0) execution time : 0.016 s
Press any key to continue.
The only behavior I would have expected to see after forcing the cz variable alignment on 8 bytes is thatcz was allocated to an address whose value is multiple of 8, I would not have expected to see follow cz from the padding. How come this behavior?
Also I expected that the number of bytes corresponding to the padding combined with the data size of 1 byte would result in 8, instead the padding occupies 6 bytes for which reason?
Stacks commonly grow downward. There is no essential reason for this; it is largely simply the result of historical development. A region of memory is allocated for the stack, the stack pointer is set to point to the high end of it, and the main routine of the program is started. As the program needs more stack space, it decreases the stack pointer.
What appears to be happening in your example is that the compiler is assigning space for objects in the order it encounters them. dx is seen first, so it is assigned the next available space on the stack, 0x28ff13. Then ca is seen, and it is assigned 0x28ff12. We see that, as the stack grows, it proceeds from higher addresses (where it started) to lower addresses.
When the compiler gets to cz, for which you have requested eight-byte alignment, the compiler jumps to the next multiple of eight (still in the downward direction), which is 0x28ff08.
Certainly the compiler could have looked at the whole situation (instead of looking at each object one at a time) and put cz at 0x28ff10 and put the other objects around it, using less stack space. If you compile with optimization enabled, the compiler might do that. On the other hand, the compiler might have a requirement on your platform to keep the stack pointer aligned to eight bytes (or more), so rearranging these particular objects would not have saved any stack space anyway.
There are no rules in the C standard about this. The compiler is free to arrange its stack as it chooses.
Hi i came across with this simple c program but i cant understand how this code works:
#include <string.h>
#include <stdio.h>
char *a = "\0hey\0\0"; /* 6 */
char *b = "word\0up yo"; /* 10 */
char *c = "\0\0\0\0"; /* 4 */
int main(void)
{
char z[20];
char *zp = z;
memcpy(zp, a, strlen(a)+1);
memcpy(zp, b, strlen(b)+1);
memcpy(zp, c, strlen(c)+1);
/* now z contains all 20 bytes, including 8 NULLs */
int i;
for(i = 0; i < 20; i++){
if (z[i] == 0){
printf("\\0");
}
printf("%c", z[i]);}
return 0;
}
I was expecting that printing z the output would be :
\0hey\0\0\0word\0up yo\0\0\0
But instead I am getting :
\0ord\0\0\0\0\0\0\0\0\0\0\0\0???Z
Finally , when i print a instead of z i get the right output.
Can anyone explain to me why this happens ? Thanks in advance.
EDIT: How i could concatenate such strings?
Strings in C are zero-terminated; the functions in the standard C library assume this property. In particular, the function strlen returns the number of non-zero characters from the start of the string. In your example, strlen(a) is equal to 0, already as the first character of a is zero.
The code will have the following effect:
memcpy(zp, a, strlen(a)+1);
Now zp still contains \0, because strlen(a) is 0, so 1 character is copied.
memcpy(zp, b, strlen(b)+1);
Now zp contains word\0: five characters copied.
memcpy(zp, c, strlen(c)+1);
Now just the first character of zp is overwritten, so it contains \0ord\0.
Finally , when i print a instead of z i get the right output. Can anyone explain to me why this happens ? Thanks in advance.
That's because a, b, and c happen to be allocated sequentially in the memory. When you print "20 bytes starting from the start of a", you're actually looking at the memory past the latest byte of a. This memory happens to contain b. So you actually start reading b. Same goes for b and c. Note that this is by no means guaranteed. Looking past the memory allocated for a char * is in fact an instance of undefined behaviour.
How i could concatenate such strings?
In general, there is no way how to find the length of such "strings" in the runtime. I would not call them strings as such, since "string" has a specific meaning in the C language - it refers to zero terminated strings, while your's are simply regions of memory.
However, since you know the size at compile time, you can use that. To avoid magic numbers in the code, it's better to use char arrays instead of char pointers, because then you can use the sizeof operator. However, note that all string literals in C are implicitly zero terminated! To fit the result in the 20-byte buffer, you'll want to use sizeof(x) - 1:
char a[] = "\0hey\0\0"; /* 6 */
char b[] = "word\0up yo"; /* 10 */
char c[] = "\0\0\0\0"; /* 4 */
memcpy(zp, a, sizeof(a) - 1);
zp += sizeof(a) - 1;
memcpy(zp, b, sizeof(b) - 1);
zp += sizeof(b) - 1;
memcpy(zp, c, sizeof(c) - 1);
I recently learnt nios II SOPC, and I encountered the process of writing into and reading from memory. The use of pointer int* and char* lets me have two different results. The code is as follow.
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
The code for "int*" is as follow
#include "system.h"
#include "stdio.h"
int main()
{
char* n = (char*) MEMORY_0_BASE; //the address for first block of memory
int i;
for(i=0;i<16;i++)
{
*(n+i)=i;
}
for(i=0;i<16;i++)
{
printf("Du lieu tai o nho thu %d la %d\n", i , *(n+i));
}
while(1);
}
The result for using "int*" is 0,1,2,...,15 while the result for "char*" is 3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15. I cannot explain why this is the case.
The following is my code for the memory block
module memory
#(parameter DATA_WIDTH=32, parameter ADDR_WIDTH=4)
(
input iClk, iReset_n,
input iRead_n, iWrite_n,
input [ADDR_WIDTH-1:0] iAddress,
input [DATA_WIDTH-1:0] iData,
output [DATA_WIDTH-1:0] oData
);
reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_reg;
always#(posedge iClk)
begin
if(!iWrite_n)
mem[iAddress] = iData;
if(!iRead_n)
addr_reg = iAddress;
end
assign oData = mem[addr_reg];
endmodule
This is my speculation based on the observed behaviour.
Your memory device consists of 16 x 32-bit integers. My speculation is that the compiler which likes to address things in bytes is effectively masking out the lowest two bits of the address. The zeroth register has the address MEMORY_0_BASE + 0 * 4, the first register has the address MEMORY_0_BASE + 1 * 4, the second register has the address MEMORY_0_BASE + 2 * 4 etc.
If you store ints to the registers using an int pointer, each time you increment the int pointer, the C pointer arithmetic actually adds sizeof(int) = 4 to the address in the pointer, so the sequence of addresses to which ints are stored is as above.
If you store chars using a char pointer, each time you increment the char pointer, the C pointer arithmetic adds sizeof(char) = 1 to the address in the pointer. The code attempts to store the first four chars (0, 1, 2, 3) to MEMORY_0_BASE + 0, MEMORY_0_BASE + 1, MEMORY_0_BASE + 2, MEMORY_0_BASE + 3. If, as I believe, the bottom two bits of the pointer are being masked, all of those addresses store to MEMORY_0_BASE and, by the time you are done, the value in it is 3.
Similarly for the second four chars (4, 5, 6, 7). They get stored to MEMORY_0_BASE + 4, MEMORY_0_BASE + 5, MEMORY_0_BASE + 6, MEMORY_0_BASE + 7, which all map to MEMORY_0_BASE + 4 after masking, leaving it containing the number 7 and so on.
That's how you get the sequence 3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15.
#include <stdio.h>
void main()
{
char *s= "hello";
char *p = s;
printf("%c\t%c", p[0], s[1]);
}
output of this program is : h e
Can anyone please explain how this program is working? I'm relatively new to c..
p[0] is identical to *(p+0) , similarly goes for s[1] . [] always operates on a pointer and is same for arrays and pointers.
Note - There is no array declared in your program.
Please note the following facts first( They are neutral to programming LANGUAGE )
Any pointer has/ takes memory equals to size of your systems data bus
even void* takes size equals size of your systems data bus
Now size of data bus is size of processors data fetching/manipulating capacity, you might heard 32 Bit processor, 64 Bit processor
Finally processors data fetching/manipulating capacity equals size of your int, that's why we use following code to calculate Architecture of CPU
#include<stdio.h>
int main(){
if(sizeof(int)==2) {
printf("\n 16 Bit Architecture, may be using DOS & Turbo C++ IDE");
}else if(sizeof(int)==4) {
printf("\n 32 Bit Architecture");
}else {
printf("\n 64 Bit Architecture");
}
return 0;
}
I have a function to convert integer to string .The function is
char * Int_String(int Number)
{
char* result;
NAT size = 1;
if (Number > 9) {
size = (NAT)log10((double) Number) + 1;
} else if (Number < 0) {
size = (NAT)log10((double) abs(Number)) + 2; /* including '-' */
}
size++; /* for '\0' */
result = (char *) memory_Malloc(sizeof(char) * size);
sprintf(result, "%d", Number);
return result;
}
NAT is typedef unsigned int
Number is int
I am using this function in the following manner
char *s2;
char **Connections;
Connections = memory_Malloc(nc*sizeof(char*));
char con[]="c_";
k1=1;
for (i=0; i<nc ; i++){
s2 = Int_ToString(k1);
Connections[i]= string_Conc(con,s2);
string_StringFree(s2);
k1= k1+1;
}
And the functionschar* string_Conc(const char *s1, const char *S2) is
{
char* dst;
dst = memory_Malloc(strlen(s1) + strlen(s2) + 1);
strcpy(dst, s1);
return strcat(dst,s2);
}
I am using following methods to free its memory:
for(i=0; i<nc; i++){
memory_Free(Connections[i],sizeof(char));
}
memory_Free(Connections,nc*sizeof(char*));
The problem that i am getting is: i can free all the allocated memory when nc<=9.But when it is >=10 leakes memory in the multiple of 4 bytes with each increase in number. How can I remove the problem.Any help will be appreciated.
EDIT
void memory_Free(POINTER Freepointer, unsigned int Size)
Thanks,
thetna
You don't show the implementation of memory_Free (neither memory_Malloc), so we don't know why you need to pass the supposed size of the memory block to be freed as a 2nd parameter (the standard free() doesn't need this). However, here
memory_Free(Connections[i],sizeof(char));
it is certainly wrong: sizeof(char) is 1 on most platforms, but the size of the allocated block is at least 4 bytes for each string in the array (as the strings contain "c_" plus at least one digit plus the terminating '\0').
Update
Looking through the source code you linked, this indeed seems to be the cause of your problem! The code inside memory_Free seems to align memory block sizes - I can assume that to 4-byte boundaries, which is very common. In this case, if the passed Size is 1, it happens to be corrected to 4 - exactly the right value in case of single digit numbers as shown above! However, numbers greater than 9 are converted to (at least) two digits, thus the size of the converted string is already 5. A block of 5 bytes is most probably allocated as an aligned block of 8 bytes under the hood - but since memory_Free is always called with a Size of 1, it always frees only 4 bytes. This leaves 4 bytes leaking per each number above 9, precisely as you described in your comment above!
To fix this, you need to modify the line above to
memory_Free(Connections[i], strlen(Connections[i]) + 1);