重新分配有什么问题?

发布于 2024-12-03 17:53:01 字数 1424 浏览 1 评论 0原文

我有以下代码,您可以尝试使用 c99 filename.c; ./a.out

#include <stdio.h>
#include <stdlib.h>

typedef unsigned long long int se_t;  // stack element type

se_t stack_size = 0;
se_t *bottom_of_stack = NULL;
#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t))

#define stack_infix(op) stack_push(stack_pop() #op stack_pop())
#define do_times(x) for(int _i=0; _i<x; _i++)

void stack_push(se_t v) {
    bottom_of_stack = realloc(bottom_of_stack,
                              ++stack_size * sizeof(se_t));
    *top_of_stack = v;
}

void stack_print() {
    printf("stack(%d): \n", (int)stack_size);
    for(se_t *i = bottom_of_stack;
             i <= top_of_stack;
             i += sizeof(se_t)) {
        printf("%p: %d \n", (void*)i, (int)*i);
    }
}

int main() {
    int i = 2;
    do_times(3) {
        stack_push(i*=i);
        stack_print();
    }
}

每次向堆栈推送内容时,我都会重新分配堆栈。这是输出(带有我的评论):

stack(1): 
0x105200820: 0  // realloc successfully allocated some memory for the first time 
0x105200860: 4 
stack(2): 
0x105200820: 0  // extended the memory range without moving it somewhere else
0x105200860: 4 
0x1052008a0: 16 
stack(3): 
0x105200830: 0  // reallocated the memory to some other region (see the address) 
0x105200870: 0  // and failed for some reason to copy the old data!
0x1052008b0: 0  // why?!
0x1052008f0: 256 

I have the following code which you can try using c99 filename.c; ./a.out

#include <stdio.h>
#include <stdlib.h>

typedef unsigned long long int se_t;  // stack element type

se_t stack_size = 0;
se_t *bottom_of_stack = NULL;
#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t))

#define stack_infix(op) stack_push(stack_pop() #op stack_pop())
#define do_times(x) for(int _i=0; _i<x; _i++)

void stack_push(se_t v) {
    bottom_of_stack = realloc(bottom_of_stack,
                              ++stack_size * sizeof(se_t));
    *top_of_stack = v;
}

void stack_print() {
    printf("stack(%d): \n", (int)stack_size);
    for(se_t *i = bottom_of_stack;
             i <= top_of_stack;
             i += sizeof(se_t)) {
        printf("%p: %d \n", (void*)i, (int)*i);
    }
}

int main() {
    int i = 2;
    do_times(3) {
        stack_push(i*=i);
        stack_print();
    }
}

I reallocate stack every time I push something to it. Here is the output (with my comments):

stack(1): 
0x105200820: 0  // realloc successfully allocated some memory for the first time 
0x105200860: 4 
stack(2): 
0x105200820: 0  // extended the memory range without moving it somewhere else
0x105200860: 4 
0x1052008a0: 16 
stack(3): 
0x105200830: 0  // reallocated the memory to some other region (see the address) 
0x105200870: 0  // and failed for some reason to copy the old data!
0x1052008b0: 0  // why?!
0x1052008f0: 256 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山川志 2024-12-10 17:53:01

指针算术已使用sizeof (basetype)。当你这样做时,

#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t))

你实际上是乘以 sizeof (se_t) 两次。

如果 bottom_of_stack 的值为 0xF000 并且 stack_size 为 2 并且 sizeof (se_t) 为 0x10

bottom_of_stack + stack_size == 0xF020
bottom_of_stack + stack_size * sizeof (se_t) == 0xF400 /* or whatever */

Pointer arithmetic already uses sizeof (basetype). When you do

#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t))

you are effectively multiplying by sizeof (se_t) twice.

if bottom_of_stack has the value 0xF000 and stack_size is 2 and sizeof (se_t) is 0x10

bottom_of_stack + stack_size == 0xF020
bottom_of_stack + stack_size * sizeof (se_t) == 0xF400 /* or whatever */
贱贱哒 2024-12-10 17:53:01

使用这个:

#define top_of_stack (bottom_of_stack + (stack_size - 1))

事实上,您存储的数据超出了分配的空间的末尾。

哦,也改变这一行:

i += sizeof(se_t)) {

应该是:

i++) {

因为 pmg 所说的指针算术。

Use this:

#define top_of_stack (bottom_of_stack + (stack_size - 1))

As it is, you're storing data past the end of the allocated space.

Oh, and change this line too:

i += sizeof(se_t)) {

Should be:

i++) {

Because of what pmg said about pointer arithmetic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文