我知道我应该使用realloc来生成一个阵列,但是在一瞬间的想法中,我这样做了。 我意识到这种方法是错误的,因为我在不分配数组的情况下通过增加它来破坏堆。 所以我基本上写垃圾。 但是当代码很小而没有其他事情发生时,我不明白为什么这不起作用。 我为前几个值得到了垃圾
#include <stdio.h> #include <stdlib.h> int main() { int **p = NULL; int i=0; int size = 5; int *n = NULL; p = malloc(sizeof(int*)); printf("p = %p \n", p); for( i=0; i < size; i++ ) { int *k; k = malloc(sizeof(int)); *k = i; p[i] = k; printf("%p, %p, val = %d \n", k, p[i], *k); } printf("Now print the array -- \n"); for( i=0; i < size; i++ ) { int *k; k = p[i]; printf("value at mem %p == %d \n", p[i], *k); } printf("now print the next values in p \n"); for( i=0; i < size; i++ ) { printf("value at %p = %p \n", p+i, *(p+i) ); } return 0; }这是代码的输出 -
p = 0x7f8ffbc031c0 0x7f8ffbc031d0, 0x7f8ffbc031d0, val = 0 0x7f8ffbc031e0, 0x7f8ffbc031e0, val = 1 0x7f8ffbc031f0, 0x7f8ffbc031f0, val = 2 0x7f8ffbc03200, 0x7f8ffbc03200, val = 3 0x7f8ffbc03210, 0x7f8ffbc03210, val = 4 Now print the array -- value at mem 0x7f8ffbc031d0 == -71290384 value at mem 0x7f8ffbc031e0 == -71290352 value at mem 0x7f8ffbc031f0 == 2 value at mem 0x7f8ffbc03200 == 3 value at mem 0x7f8ffbc03210 == 4 now print the next values in p value at 0x7f8ffbc031c0 = 0x7f8ffbc031d0 value at 0x7f8ffbc031c8 = 0x7f8ffbc031e0 value at 0x7f8ffbc031d0 = 0x7f8ffbc031f0 value at 0x7f8ffbc031d8 = 0x7f8ffbc03200 value at 0x7f8ffbc031e0 = 0x7f8ffbc03210我无法解释为什么前两个值都是垃圾,即使p和p + 1指向的内存地址是我放在那里的。
I know I should be using realloc to grow an array but in a momentary lapse of thought I did it this way. I realize the approach is wrong as I am corrupting the heap by growing it without allocating the array. So I am essentially writing garbage. But when the code is small and nothing else is happening I don't see why this should not work. I get garbage for the first few values
#include <stdio.h> #include <stdlib.h> int main() { int **p = NULL; int i=0; int size = 5; int *n = NULL; p = malloc(sizeof(int*)); printf("p = %p \n", p); for( i=0; i < size; i++ ) { int *k; k = malloc(sizeof(int)); *k = i; p[i] = k; printf("%p, %p, val = %d \n", k, p[i], *k); } printf("Now print the array -- \n"); for( i=0; i < size; i++ ) { int *k; k = p[i]; printf("value at mem %p == %d \n", p[i], *k); } printf("now print the next values in p \n"); for( i=0; i < size; i++ ) { printf("value at %p = %p \n", p+i, *(p+i) ); } return 0; }Here is the output of the code --
p = 0x7f8ffbc031c0 0x7f8ffbc031d0, 0x7f8ffbc031d0, val = 0 0x7f8ffbc031e0, 0x7f8ffbc031e0, val = 1 0x7f8ffbc031f0, 0x7f8ffbc031f0, val = 2 0x7f8ffbc03200, 0x7f8ffbc03200, val = 3 0x7f8ffbc03210, 0x7f8ffbc03210, val = 4 Now print the array -- value at mem 0x7f8ffbc031d0 == -71290384 value at mem 0x7f8ffbc031e0 == -71290352 value at mem 0x7f8ffbc031f0 == 2 value at mem 0x7f8ffbc03200 == 3 value at mem 0x7f8ffbc03210 == 4 now print the next values in p value at 0x7f8ffbc031c0 = 0x7f8ffbc031d0 value at 0x7f8ffbc031c8 = 0x7f8ffbc031e0 value at 0x7f8ffbc031d0 = 0x7f8ffbc031f0 value at 0x7f8ffbc031d8 = 0x7f8ffbc03200 value at 0x7f8ffbc031e0 = 0x7f8ffbc03210I cannot explain why the first two values are garbage even though the memory address pointed to by p and p+1 are what I put there.
最满意答案
该程序具有未定义的行为。 不过我可以解释这个程序运行的结果。
通常当内存分配请求小于段落的大小(通常等于16个字节)时,函数malloc分配一个与段大小完全相等的内存块。
所以在这个声明之后
p = malloc(sizeof(int*));在地址分配了16个字节
p = 0x7f8ffbc031c0因此,您可以使用地址
属于分配范围的0x7f8ffbc031c0和0x7f8ffbc031c8 。
由语句在循环中分配的第一个和第二个块
k = malloc(sizeof(int));是
0x7f8ffbc031d0 0x7f8ffbc031e0由于声明在同一循环中
p[i] = k;存在超出指针p指向的分配范围的存储器。
所以你有顺序表达p[i]
0x7f8ffbc031c0 - p[0] 0x7f8ffbc031c8 - p[1] 0x7f8ffbc031d0 - p[2] - Oops! the address 0x7f8ffbc031d0 is overwritten 0x7f8ffbc031d8 - p[3] 0x7f8ffbc031e0 - p[4] - Oops! the address 0x7f8ffbc031e0 is overwritten!因此,存储前两个整数的前两个地址将被覆盖。
The program has undefined behavior. Nevertheless I can explain the result of this program run.
Usually when a memory allocation request is less than the size of the paragraph that is usually equal to 16 bytes then the function malloc allocates a chunk of memory exactly equal to the size of paragraph.
So after this statement
p = malloc(sizeof(int*));there was allocated 16 bytes at address
p = 0x7f8ffbc031c0Thus you can use addresses
0x7f8ffbc031c0 and 0x7f8ffbc031c8 that belong to the allocated extent.
The first and the second chunks allocated in the loop by the statement
k = malloc(sizeof(int));is
0x7f8ffbc031d0 0x7f8ffbc031e0In the same loop due to the statement
p[i] = k;there are accesses the memory beyond the allocated extent pointed to by the pointer p.
so you have for the expression p[i] sequentially
0x7f8ffbc031c0 - p[0] 0x7f8ffbc031c8 - p[1] 0x7f8ffbc031d0 - p[2] - Oops! the address 0x7f8ffbc031d0 is overwritten 0x7f8ffbc031d8 - p[3] 0x7f8ffbc031e0 - p[4] - Oops! the address 0x7f8ffbc031e0 is overwritten!So the first two addresses where the first two integers were stored are overwritten.
更多推荐
发布评论