指向数组类型的指针,c

指向数组类型的指针,c,第1张

概述如果我要说 int (*i)[10] = malloc(size(int *) * 5); 这会分配看起来像的内存 { (int *) , (int *) , (int *) , (int *) , (int *) } 现在,当我取消引用这些指针中的任何一个时,我得到了未初始化的内存, 除了问责原因之外,还有什么需要在(* i)之后包含[10]而不是使用双指针? 使用10实际上是否为10个整数分配 如果我要说
int (*i)[10] = malloc(size(int *) * 5);

这会分配看起来像的内存

{ (int *),(int *),(int *) }

现在,当我取消引用这些指针中的任何一个时,我得到了未初始化的内存,

除了问责原因之外,还有什么需要在(* i)之后包含[10]而不是使用双指针?

使用10实际上是否为10个整数分配空间,因为如果它确实我们将无法访问它?

解决方法 辩解书

有一些混乱,可能是我自己;为此,我道歉.从某个地方,大概是answer到x4u,我复制了这个符号:

int (*arr)[10] = malloc(sizeof(*arr) * 5);

紧接着我的主要答案是解决这个C语句.在页面下方一英里处有一个章节标题为“原始问题”,其中涉及问题中的内容,即:

int (*i)[10] = malloc(size(int *) * 5);

答案中的许多分析和评论对原始问题仍然有效.

回答

考虑C语句:

int (*arr)[10] = malloc(sizeof(*arr) * 5);

arr的类型是’指向10 int数组的指针’.因此,sizeof(* arr)的值是10 * sizeof(int).因此,内存分配为5个10 int数组分配了足够的空间.这意味着arr [0]到arr [4]中的每一个都是10个int值的数组,因此arr [2] [7]是一个int值.

如何证明这一点?一些代码,我想使用C99 printf()格式.它干净地编译并在valgrind下运行干净.

示例代码:pa.c

#include <stdlib.h>#include <stdio.h>#include <inttypes.h>int main(voID){    int (*arr)[10] = malloc(sizeof(*arr) * 5);    printf("sizeof(voID*) = %zu\n",sizeof(voID*));    printf("sizeof(arr)   = %zu\n",sizeof(arr));    printf("sizeof(*arr)  = %zu\n",sizeof(*arr));    printf("sizeof(int)   = %zu\n",sizeof(int));    printf("arr           = 0x%" PRIXPTR "\n",(uintptr_t)arr);    printf("arr + 1       = 0x%" PRIXPTR "\n",(uintptr_t)(arr + 1));    putchar('\n');    for (int i = 0; i < 5; i++)    {        printf("arr[%d]        = 0x%" PRIXPTR "\n",i,(uintptr_t)arr[i]);        for (int j = 0; j < 10; j++)        {            arr[i][j] = 10 * i + j;            printf("&arr[%d][%d]    = 0x%" PRIXPTR "\t",j,(uintptr_t)&arr[i][j]);            printf("arr[%d][%d] = %d\n",arr[i][j]);        }    }    free(arr);    return 0;}

编译和追踪

$gcc -O3 -g -std=c99 -Wall -Wextra -o pa pa.c$valgrind pa==28268== Memcheck,a memory error detector==28268== copyright (C) 2002-2011,and GNU GPL'd,by Julian Seward et al.==28268== Using Valgrind-3.7.0 and libVEX; rerun with -h for copyright info==28268== Command: pa==28268== sizeof(voID*) = 8sizeof(arr)   = 8sizeof(*arr)  = 40sizeof(int)   = 4arr           = 0x100005120arr + 1       = 0x100005148arr[0]        = 0x100005120&arr[0][0]    = 0x100005120 arr[0][0] = 0&arr[0][3]    = 0x100005124 arr[0][4] = 1&arr[0][2]    = 0x100005128 arr[0][2] = 2&arr[0][3]    = 0x10000512C arr[0][3] = 3&arr[0][4]    = 0x100005130 arr[0][4] = 4&arr[0][5]    = 0x100005134 arr[0][5] = 5&arr[0][6]    = 0x100005138 arr[0][6] = 6&arr[0][7]    = 0x10000513C arr[0][7] = 7&arr[0][8]    = 0x100005140 arr[0][8] = 8&arr[0][9]    = 0x100005144 arr[0][9] = 9arr[1]        = 0x100005148&arr[1][0]    = 0x100005148 arr[1][0] = 10&arr[1][5]    = 0x10000514C arr[1][6] = 11&arr[1][2]    = 0x100005150 arr[1][2] = 12&arr[1][3]    = 0x100005154 arr[1][3] = 13&arr[1][4]    = 0x100005158 arr[1][4] = 14&arr[1][5]    = 0x10000515C arr[1][5] = 15&arr[1][6]    = 0x100005160 arr[1][6] = 16&arr[1][7]    = 0x100005164 arr[1][7] = 17&arr[1][8]    = 0x100005168 arr[1][8] = 18&arr[1][9]    = 0x10000516C arr[1][9] = 19arr[2]        = 0x100005170&arr[2][0]    = 0x100005170 arr[2][0] = 20&arr[2][7]    = 0x100005174 arr[2][8] = 21&arr[2][2]    = 0x100005178 arr[2][2] = 22&arr[2][3]    = 0x10000517C arr[2][3] = 23&arr[2][4]    = 0x100005180 arr[2][4] = 24&arr[2][5]    = 0x100005184 arr[2][5] = 25&arr[2][6]    = 0x100005188 arr[2][6] = 26&arr[2][7]    = 0x10000518C arr[2][7] = 27&arr[2][8]    = 0x100005190 arr[2][8] = 28&arr[2][9]    = 0x100005194 arr[2][9] = 29arr[3]        = 0x100005198&arr[3][0]    = 0x100005198 arr[3][0] = 30&arr[3][9]    = 0x10000519C arr[3][10] = 31&arr[3][2]    = 0x1000051A0 arr[3][2] = 32&arr[3][3]    = 0x1000051A4 arr[3][3] = 33&arr[3][4]    = 0x1000051A8 arr[3][4] = 34&arr[3][5]    = 0x1000051AC arr[3][5] = 35&arr[3][6]    = 0x1000051B0 arr[3][6] = 36&arr[3][7]    = 0x1000051B4 arr[3][7] = 37&arr[3][8]    = 0x1000051B8 arr[3][8] = 38&arr[3][9]    = 0x1000051BC arr[3][9] = 39arr[4]        = 0x1000051C0&arr[4][0]    = 0x1000051C0 arr[4][0] = 40&arr[4][11]    = 0x1000051C4    arr[4][12] = 41&arr[4][2]    = 0x1000051C8 arr[4][2] = 42&arr[4][3]    = 0x1000051CC arr[4][3] = 43&arr[4][4]    = 0x1000051D0 arr[4][4] = 44&arr[4][5]    = 0x1000051D4 arr[4][5] = 45&arr[4][6]    = 0x1000051D8 arr[4][6] = 46&arr[4][7]    = 0x1000051DC arr[4][7] = 47&arr[4][8]    = 0x1000051E0 arr[4][8] = 48&arr[4][9]    = 0x1000051E4 arr[4][9] = 49==28268== ==28268== HEAP SUMMARY:==28268==     in use at exit: 6,191 bytes in 33 blocks==28268==   total heap usage: 34 allocs,1 frees,6,391 bytes allocated==28268== ==28268== LEAK SUMMARY:==28268==    definitely lost: 0 bytes in 0 blocks==28268==    indirectly lost: 0 bytes in 0 blocks==28268==      possibly lost: 0 bytes in 0 blocks==28268==    still reachable: 6,191 bytes in 33 blocks==28268==         suppressed: 0 bytes in 0 blocks==28268== Rerun with --leak-check=full to see details of leaked memory==28268== ==28268== For counts of detected and suppressed errors,rerun with: -v==28268== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)$

使用GCC 4.6.1和Valgrind 3.7.0在MacOS X 10.7.2上进行测试.

原始问题

看来,实际问题是关于分配:

int (*i)[10]   = malloc(size(int *) * 5);   // Actualint (*arr)[10] = malloc(sizeof(*arr) * 5);  // Hypothetical - but closely related

i的类型与arr的类型相同,arr是指向10个int值的数组的指针.

但是,如果你在64位机器上,分配的空间就足够了,其中sizeof(int *)== 8&& sizeof(int)== 4.然后你(巧合地)为一个数组分配了足够的空间.

如果您使用的是32位机器,其中sizeof(int *)== 4&& sizeof(int)== 4,那么你只为半个数组分配了足够的空间,这对任何代码都是一件糟糕的事情.

我在主要答案中展示的代码经过调整,以证明您可以访问假设中分配的五个数组的空间.通过修改内存分配,您只能使用一个数组的空间.随着这一变化,我评论的其余部分应用不变.

总结

以上是内存溢出为你收集整理的指向数组类型的指针,c全部内容,希望文章能够帮你解决指向数组类型的指针,c所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1256113.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存