-7

让我们假设这段代码:

int i,j=0;
char* block = (char*) (0x9000);
char table[4]= {0x01,0x02,0x03,0x04};
for (i=0; i< 45567; i++) {
    *(block +i)= table[j]; 
    j++; 
    if (j==4)
        j=0;
}

我想问一下:

  1. 内存是block在栈中还是在堆中分配的?
  2. 这段代码可能会出现什么问题?
  3. 我可以free(block)在这段代码的末尾使用吗?
4

6 回答 6

11

您实际上没有分配任何内存,无论是在堆栈上还是在堆上。您只是将变量指向一个地址,然后假装那里的内存属于您。

这在 C 或 C++ 中都是不合法的,并且通常不会起作用。“不工作”在这里真的可以意味着任何事情。而且由于代码是非法的,指针是否可以是freed 的问题是没有意义的。

(在非常特定的设置中,如果编译器和硬件支持它,则用于写入特定的硬件地址。但这里不是这种情况。)

于 2015-09-15T13:40:49.857 回答
3

块内存是在栈中还是在堆中分配的?

两者都不。它根本没有分配:您为指针分配了一个任意数字,因此任何读取或写入的尝试block都是未定义的行为。

我可以在这段代码的末尾使用 free(block) 吗?

那也是未定义的行为。允许您传递的指针free必须来自malloccallocrealloc

注意: 未定义行为是当你的程序做了一些标准不允许的事情并且编译器没有捕获时发生的事情的正式名称。在许多情况下,未定义的行为会导致崩溃,但不幸的是,在某些情况下,您的程序似乎可以工作。

于 2015-09-15T13:41:41.520 回答
2

你不需要释放任何你没有要求获得空间的东西,你在没有 realloc malloc 或 calloc 的情况下声明的所有东西都不需要释放,它们存储在静态存储或堆栈上。

您还strdup需要释放一些其他功能,但简单的声明不需要free

于 2015-09-15T13:41:04.087 回答
0

永远不应该调用free不是从 、 或 之一返回的malloc指针callocrealloc

知道你的平台上是否0x9000是一个有效的、可写的地址吗?

于 2015-09-15T13:42:58.403 回答
0

该数组table可能在堆栈上。希望指针block位于一些其他未占用的内存中,也许它已被分配,而 0x9000 是一些特殊地址,没有足够的代码来确定上下文。根据架构,可能允许也可能不允许盲目写入任意地址。

所以回答你的问题:

  • 如果没有 malloc/calloc/realloc,你不应该释放,结果是不确定的;确实存在例外,例如,如果系统在您使用之前分配了空间,但通常如果系统分配内存,它会自行释放它

  • 这段代码可能会出现各种问题,但取决于架构;我在完全合法的平台上写过,其他人会抛出各种异常;可能是它用 1 到 4 的重复序列填充了从 0x9000 开始的 45567 个字节,或者它可能会使您的机器崩溃;C会高兴地让你在脚下开枪

于 2015-09-15T13:54:27.647 回答
0

您所做的非常危险。您不应该选择随机地址并将其分配给指针以将数据复制到内存中。这就像将核废料倾倒在地球上的随机位置。相反,您应该使用 malloc 或 new 来分配内存安全。

于 2015-09-15T15:55:50.097 回答