指针数组类型,C [英] pointer to array type, c

查看:109
本文介绍了指针数组类型,C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我是说

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

这将分配的内存,看起来像

this would allocated memory that looks like

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

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

现在,当我提领这些指针我得到未初始化的内存的人,

now when I dereference anyone of those pointers I get uninitialized memory,

所以,不是问责的原因外,是否有任何需要包括后[10](* I)而不是使用双指针?

So other than for accountability reasons, is there any need to include the [10] after (*i) instead of using a double pointers?

是否使用10实际上十分整数分配空间,因为如果它这样做,我们不会将能够访问它?

Does using the 10 actually allocate space for ten ints, because if it did we wouldn't be able to access it?

推荐答案

有一些混乱,可能是我的一部分;对于这一点,我很抱歉。的不知从哪里presumably的 x4u 回答,我复制的符号:

Apologia

There is some confusion, probably on my part; for that, I apologize. From somewhere, presumably the answer by x4u, I copied the notation:

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

我的主要答案,紧接着,针对这款C声明。有一节一英里打倒小节标题原始的问题的页面,解决什么是问题,即:

My main answer, immediately following, addresses this C statement. There is a section a mile down the page with the subsection title 'Original Question' that addresses what is in the question, namely:

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

很多答案的分析和评论的有效期为原来的问题。

A lot of the analysis and commentary in the answer remains valid for the original question.

考虑C语句,

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

改编类型是'指针指向10 INT 阵'。因此,的sizeof的值(* ARR) 10 * sizeof的(INT)。因此,内存配置为10 INT 5阵列分配足够的空间。这意味着每个改编的[0] 改编[4] 10 INT 值,因此改编[2] [7] INT 值。

The type of arr is 'pointer to array of 10 int'. Therefore, the value of sizeof(*arr) is 10 * sizeof(int). Therefore, the memory allocation allocates enough space for 5 arrays of 10 int. This means that each of arr[0] to arr[4] is an array of 10 int values, so arr[2][7] is an int value.

如何证明这一点?有些code,我想用C99 的printf()格式。它完全编译并在的valgrind 顺利运行。

How to demonstrate this? Some code, I suppose using C99 printf() formats. It compiles cleanly and runs cleanly under valgrind.

#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", i, j, (uintptr_t)&arr[i][j]);
            printf("arr[%d][%d] = %d\n", i, j, 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*) = 8
sizeof(arr)   = 8
sizeof(*arr)  = 40
sizeof(int)   = 4
arr           = 0x100005120
arr + 1       = 0x100005148

arr[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] = 9
arr[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] = 19
arr[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] = 29
arr[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] = 39
arr[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)
$

测试上的MacOS X 10.7.2使用GCC 4.6.1和3.7.0 Valgrind的

Testing on MacOS X 10.7.2 with GCC 4.6.1 and Valgrind 3.7.0.

实际的问题,似乎是关于分配的:

The actual question, it seems, was about the allocation:

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

类型的 I 相同的改编的类型,指针指向10数组 INT 值。

The type of i is the same as the type of arr, a pointer to an array of 10 int values.

不过,如果你是一个64位的机器上分配的空间只够其中的sizeof(INT *)== 8安培;&安培;的sizeof(INT)== 4 。那么你就(巧合)分配足够的空间,一个阵列。

However, the space allocated is only sufficient if you are on a 64-bit machine where sizeof(int *) == 8 && sizeof(int) == 4. Then you have (coincidentally) allocated enough space for one array.

如果你是一个32位的机器上,其中的sizeof(INT *)== 4安培;&安培;的sizeof(INT)== 4 ,那么你就只分配了足够的空间了半个多阵列,这是做任何code件可怕的事情。

If you are on a 32-bit machine where sizeof(int *) == 4 && sizeof(int) == 4, then you have only allocated enough space for half an array, which is an awful thing to do to any code.

在code我在主要答覆显示进行了调整,证明你可以访问在假想空间分配五个阵列的价值。修订后的内存分配,你只能使用一个空间阵列的价值。随着这种变化,我的评论的其余部分适用不变。

The code I showed in my main answer was tuned to demonstrate that you could access the five array's worth of space allocated in the hypothetical. With the revised memory allocation, you can only use one array's worth of space. With that change, the rest of my commentary applies unchanged.

这篇关于指针数组类型,C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆