在c中使用malloc进行多个一行分配

时间:2016-07-13 13:52:05

标签: c memory variable-assignment assignment-operator

假设以下声明:

int *numbers, *inverse;
numbers = inverse = (int *)malloc(n * sizeof(int));

我很想知道这里发生了什么 - 我知道它是正确的,所以首先分配inverse的内存。然后我将numbers设置为inverse,这是否意味着numbers的内存位置将与inverse相同?或者它是否在&numbers&inverse位置分配了相同数量的内存?

例如,如果我执行类似inverse[i] = 5的操作,则表示numbers[i] == 5

7 个答案:

答案 0 :(得分:8)

你有:

${release}

这和写作一样:

int *numbers, *inverse;
numbers = inverse = (int *)malloc(n * sizeof(int));

变量int *inverse = (int *)malloc(n * sizeof(int)); int *numbers = inverse; 只有numbers中指针的副本 - 它指向同一个地方。但是,您可能会使用一个指针迭代数组,同时从函数返回另一个指针,这可能是获得两个副本的一个很好的理由。

只有一个内存分配;需要单次调用inverse来释放分配的内存。传递给free()的值与分配给free()inverse的原始值相同。

你也问:

  

如果我执行类似numbers的操作,则表示inverse[i] = 5

如果您未更改numbers[i] == 5inverse中存储的值,并且numbers位于i范围内0然后,在赋值之后,相等就会成立。指针是相同的(相同类型,相同的值),因此索引它们会产生相同的结果。当然,这也意味着(n-1)

答案 1 :(得分:4)

第一项工作是删除多余的(int*)强制转换(如果类型不是内置的,这样的方案甚至可能有害)。这是C和C ++之间的差异之一。

malloc(n * sizeof(int));返回类型为void*的指针。

该指针已分配给inverse

表达式 inverse = malloc(n * sizeof(int))的类型为int*。因此,可以将其有效地分配给numbers

要非常清楚,malloc只会被调用一次,因此您应该只调用free一次。

答案 2 :(得分:4)

TL; DR,是的,inversenumbers都指向同一个记忆。

长答案为什么部分,引用C11,章节§6.5.16,分配运算符 (强调我的)

  

[...] An   赋值表达式在赋值后具有左操作数的,但不是   一个左值。赋值表达式的类型是左操作数将具有的类型   左值转换后

因此,正如您正确提到的for right-to-left associativity of the assignment operator =,评估看起来像

numbers = ( inverse = (int *)malloc(n * sizeof(int)) );

所以,一旦评估inverse = (int *)malloc(n * sizeof(int))

  • 此表达式的值是赋值后的inverse的值
  • 此外,该类型与inverse
  • 的类型相同

且两者都有效)因此,下一个评估与

相同
 numbers = inverse;

所以,(如果你想要),你可以分解像

这样的陈述
if ( (inverse = malloc(n * sizeof*inverse )) )  //error check, just saying
      numbers = inverse;

and finally, if you're wondering why I removed the cast, see this discussion for more info on this.

答案 3 :(得分:3)

只分配了一块内存,inversenumbers都指向同一块。

我们可以通过实验验证。

#include <assert>

int main() {
    int n = 100;
    int *numbers, *inverse;
    numbers = inverse = (int *)malloc(n * sizeof(int));

    numbers[0] = 10;
    inverse[0] = 20;

    // If numbers and inverse point to the same memory, then we would expect
    // that numbers[0] is now 20.
    assert(inverse[0] == 20);
    assert(numbers[0] == 20);
}

答案 4 :(得分:1)

是的,你正在分配一块内存。这是指针的魔力!

答案 5 :(得分:0)

这里分配一块内存并将地址存储在两个指针中。所以两个指针都指向同一个地址

答案 6 :(得分:-2)

在C中,作业(=+=,...)是+-等运算符。它产生左边的值手边的操作员。请参阅标准6.5.16p3它们是正确的关联,评估顺序是:

numbers = ( inverse = malloc(n * sizeof(int)) );

(不要将malloc和朋友或void *的结果一般地投射到指针上。它在C中不是必需的并且可能有害。)

因此number获得与inverse相同的。对于正确的赋值,返回的是malloc

强调:这与指针无关:

int i, k;
i = k = 4;

是完全相同的原则。

编辑:

明确说明(再次):对于每个运营商,分配的右侧完全一次。您不希望f(x) + g(x) + h(x)h调用两次。

对于指针:malloc返回指向内存块的指针,两个指针都具有相同的值,因此它们指向相同的内存块。由于两者具有相同的类型,因此您可以使用两者来访问内存块。