对于家庭作业,我必须构建以下简单方案。
我的尝试如下:
#include <stdlib.h>
int main() {
char* heap1P = malloc(sizeof(char**));
char* heap2P = malloc(sizeof(char*));
char* heap3P = malloc(sizeof(char));
*heap3P = 'X';
*heap2P = heap3P;
*heap1P = heap2P;
char*** stackP = heap1P;
puts("stack | heap ");
printf("%p [%p] | %p [%p] => %p [%p] => %c [%p] \n", stackP, &stackP, *heap1P, heap1P, *heap2P, heap2P, *heap3P, heap3P);
return EXIT_SUCCESS;
}
首先,我在内存中分配空间,然后设置值。 输出类似于(格式:值[地址]):
stack | heap
0x55a1e184f260 [0x7fff05e55c08] | 0xffffff80 [0x55a1e184f260] => 0xffffffa0 [0x55a1e184f280] => X [0x55a1e184f2a0]
如您所见,堆栈值包含第一个堆值的地址。但是堆值不正确。它们不包含以下堆值的地址。
为什么堆值不包含给定的地址?
答案 0 :(得分:5)
问题仅在于您已将各种指针声明为char *
。它看起来似乎并不重要,因为在常见的实现中,所有指针都具有相同的表示形式。但是,一旦取消引用它们,它就变得至关重要!
让我们看看以下语句:
*heap3P = 'X';
*heap2P = heap3P;
第一个是正确的:heap3P
是char *
,而*heap3P
被分配了char
,在这里一切都很好。
第二个太可怕了。由于heap2P
是char *
,因此heap3P
如果转换为整数并修整为char
!长话短说:您只存储指针中的一个字节...如果仔细看一下这些值,您会发现不同的heapx
实际上是单字节值...
修复很简单:
char*** heap1P = malloc(sizeof(char**));
char** heap2P = malloc(sizeof(char*));
char* heap3P = malloc(sizeof(char));
并且代码在没有警告的情况下编译并按预期运行!
答案 1 :(得分:0)
我想你会想要类似的东西:
typedef struct heap {
char val;
struct heap *next;
} heap_t;
int main()
{
// allocate first
heap_t *head = malloc(sizeof(heap_t));
head->val = 'A';
// allocate second node
head->next = malloc(sizeof(heap_t));
head->next->val = 'B';
head->next->next = malloc(sizeof(heap_t));
head->next->next->val = 'X';
heap_t *tmp = head;
for (int i = 0; i < 3; i++, tmp = tmp->next) {
printf("[%p, %c]\n", tmp, tmp->val);
}
}
请注意,这是一个快速草稿,您当然应该在函数内创建新节点,而不是我在此处进行的手动操作。不要忘记以后释放内存。