【问题标题】:Referencing memory that is overwritten by a memmove引用被 memmove 覆盖的内存
【发布时间】:2015-01-11 06:52:21
【问题描述】:

我有以下代码:

int** x;

// Add 4 int pointers to x - code ommitted

// Pop the first element
int* a = x[0];
memmove(&x[0], &x[1], sizeof(int*) * 3);
x = realloc(x, sizeof(int*) * 3);

// Some code that uses 'a' - ommitted

据我了解,a 现在指向x 指向的第一个位置。但是,由于memmove,该内存位置现在实际上包含以前在x[1] 上的数据。

看看这段代码是如何使用的,a 似乎实际上应该指向之前在x[0] 上的值。我的问题是,如果该内存位置现在已被 x[1] 中的内容替换,a 怎么可能包含先前的值?

【问题讨论】:

  • 您在a 中找到X[0] 的副本,无论X[0] 曾经指向的任何位置
  • 你的理解(或你的措辞)是错误的。 a 指向存储在x[0] 中的任何地址,该值向下移动一个与a 无关,也无关紧要。该地址有 两个 副本;轮班前ax[0] 中的一个。之后,有一个(在a)。
  • @WhozCraig memmove(&x[0], &x[1], sizeof(int*) * 3); 看起来不错,我认为这将导致未定义的行为,因为它们是两个不同的指针,并且从未有过 sizeof(int *) * 3 的内存,它本来应该是 sizeof(int) * 3
  • @WhozCraig 您的评论(您解释它的方式)实际上是通过问题回答的。我的理解是错误的。如果你把它作为答案,我可以接受。
  • @Gopi 假设 OP 已经有效地将x 设置为指向四个int*(例如int **x = malloc(4 * sizeof(*x));,那么memmove 是有效且明确定义的。它实际上与memmove(x, x+1, sizeof(*x)*3);(我更喜欢它的语法而不是 OP,但这比其他任何东西都更重要)。

标签: c memmove


【解决方案1】:

a 是堆栈上的一个变量,在您更改(通过 memmove)x[0] 的值之前,您将 x[0] 的值分配给了该变量。因此,a 将保留 x[0] 的值,并且数组 x 将原始的 x[1],x[2],x[3] 存储在 x[0],x[1],x[2]

所以基本上 a 充当局部变量,它是 x[0] 处数据的副本。所述数据是一个整数指针,但可以是其他任何东西。

【讨论】:

  • 虽然指针a在栈上,但它指向的实际数据在堆上,对吧?这些数据不会被覆盖吗?
  • @thameera 这个答案是正确的,我的只会复制它,所以如果有什么你可以/应该接受它。关于指向堆的实际数据,这取决于您存储在x[0] 中的内容。 没有这个必须在堆上。 int ar[4]; int *x[4] = {ar,ar+1,ar+2,ar+3}; 那里,没有堆,你的代码仍然对 x 有效。
猜你喜欢
  • 2015-01-23
  • 2023-03-17
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 2018-06-21
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多