指针和一阵列的差 [英] The difference of the pointer and a array

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

问题描述

我有一块code波纹管的,什么是他们的区别呢?
第一个, BUF struct的元素的地址比结构的4大而第二个是没有的。

首先

 的#include<&stdio.h中GT;typedef结构一
{
    INT I;
    烧焦BUF []; //这里
}一个;诠释的main()
{
    A * PA =的malloc(sizeof的(A));
    的char * p =的malloc(13);
    的memcpy(对的helloworld,10);
    的memcpy(纸张> BUF,P,13);    的printf(%X%X%d个%S \\ n,纸张> BUF,PA(字符*)的PA> BUF - (字符*)PA,纸张> BUF);
}

  typedef结构一
{
    INT I;
    字符* BUF; //这里
}一个;


解决方案

第一个是C99灵活数组成员。第二个是当你没有C99或更高可靠的后备。

通过一个灵活的数组成员,你分配你需要的阵列与主体结构沿空间:

  A * PA =的malloc(sizeof的(A)+ strlen的(字符串)+ 1);纸张和GT; I =指数;
的strcpy(纸张> BUF,字符串);......每年使用...免费(PA);

至于内存分配得好, BUF 成员没有大小(因此的sizeof(A)==的sizeof(INT)除非有因为阵列对准的填充问题 - 例如,如果你有一个灵活的阵列双击

另一种需要两根分配(和两个版本),或设置一些护理:

  typedef结构A2
{
    INT I;
    字符* BUF;
} A2;A2 * PA2 = malloc的(sizeof的(A2));
pa2->的buff =的strdup(字符串);...使用... PA2免费(pa2->的buff);
免费(PA2);

或者

  A2 * PA2 =的malloc(sizeof的(A2)+ strlen的(字符串)+ 1);
pa2->的buff =(字符*)PA2 +的sizeof(A2);...使用... PA2免费(PA2);

请注意,使用A 2需要更多的存储器,可以由指针(单分配)的大小,或由指针的大小和用于第二存储器分配的开销(双重分配)。

您有时会看到一些被称为使用的'结构黑客';这predates C99标准,并通过灵活的数组成员废弃。在code这个样子:

  typedef结构A3
{
    INT I;
    炭的buf [1];
} A3;A3 * PA3 = malloc的(sizeof的(A3)+的strlen(字符串)+ 1);
的strcpy(pa3-> BUF,字符串);

这是几乎相同的柔性阵列成员,但结构更大。在这个例子中,在大多数机器上,结构 A3 将是8个字节长(而不是4个字节 A

GCC有零长度数组一定的支撑;您可能会看到结构与黑客0阵列维度是不可移植到不模仿任何GCC编译器。

这就是所谓的'结构黑客,因为它不能保证语言标准便携式(因为你正在访问的声明数组的边界之外)。不过,根据经验,它始终工作,并很可能会继续这样做。不过,你应该使用preference灵活的阵列成员的结构黑客。


ISO / IEC 9899:2011§6.7.2.1结构和联合说明符


  

¶3结构或联合不得含有不完整或函数类型的成员(因此,
  的结构不应含有自己的一个实例,但也可以包含一个指向一个实例
  本身),除了一个结构的最后一个成员与一个以上的命名构件
  可能有不完整的数组类型;这样的结构(含,可能任何工会
  递归,即这种结构的构件)不得结构的部件或
  数组的元素


  
  

¶18作为一个特殊情况下,结构的与一个以上的命名构件的最后一个元件可
  有一个不完整的数组类型;这就是所谓的的灵活的数组成员的。在大多数情况下,
  柔性阵列构件被忽略。具体地,结构的尺寸是因为如果
  除了灵活的阵列成员被省略,它可能有超过尾随填充
  遗漏意味着。然而,当 (或 - > )。运营商有一个左操作数是
  (指针)具有灵活数组成员和正确的操作名称的结构
  部件,它的行为就好像该构件用最长阵列代替(具有相同的
  元素类型),不会使结构不是被访问的对象大;该
  阵列的偏移应保持柔性阵列构件的,即使这将不同
  从更换阵列。如果这个数组就没有的元素,它的行为就好像
  它有一个元素,但如果任何试图访问该行为是不确定
  元素或以产生的指针1过去它


I have a piece of code bellow,and what's the difference of them? The first one,the address of buf element of the struct is 4 bigger than that of the struct while the second one is not.

First

#include <stdio.h>

typedef struct A
{
    int i;
    char buf[];  //Here
}A;

int main()
{
    A *pa = malloc(sizeof(A));
    char *p = malloc(13);
    memcpy(p, "helloworld", 10);
    memcpy(pa->buf, p, 13);

    printf("%x %x %d %s\n", pa->buf, pa, (char *)pa->buf - (char *)pa, pa->buf);
}

Second

typedef struct A
{
    int i;
    char *buf; //Here
}A;

解决方案

The first is a C99 'flexible array member'. The second is the reliable fallback for when you don't have C99 or later.

With a flexible array member, you allocate the space you need for the array along with the main structure:

A *pa = malloc(sizeof(A) + strlen(string) + 1);

pa->i = index;
strcpy(pa->buf, string);

...use pa...

free(pa);

As far as the memory allocation goes, the buf member has no size (so sizeof(A) == sizeof(int) unless there are padding issues because of array alignment — eg if you had a flexible array of double).

The alternative requires either two allocations (and two releases), or some care in the setup:

typedef struct A2
{
    int   i;
    char *buf;
} A2;

A2 *pa2 = malloc(sizeof(A2));
pa2->buff = strdup(string);

...use pa2...

free(pa2->buff);
free(pa2);

Or:

A2 *pa2 = malloc(sizeof(A2) + strlen(string) + 1);
pa2->buff = (char *)pa2 + sizeof(A2);

...use pa2...

free(pa2);

Note that using A2 requires more memory, either by the size of the pointer (single allocation), or by the size of the pointer and the overhead for the second memory allocation (double allocation).

You will sometimes see something known as the 'struct hack' in use; this predates the C99 standard and is obsoleted by flexible array members. The code for this looks like:

typedef struct A3
{
    int  i;
    char buf[1];
} A3;

A3 *pa3 = malloc(sizeof(A3) + strlen(string) + 1);
strcpy(pa3->buf, string);

This is almost the same as a flexible array member, but the structure is bigger. In the example, on most machines, the structure A3 would be 8 bytes long (instead of 4 bytes for A).

GCC has some support for zero length arrays; you might see the struct hack with an array dimension of 0. That is not portable to any compiler that is not mimicking GCC.

It's called the 'struct hack' because it is not guaranteed to be portable by the language standard (because you are accessing outside the bounds of the declared array). However, empirically, it has 'always worked' and probably will continue to do so. Nevertheless, you should use flexible array members in preference to the struct hack.


ISO/IEC 9899:2011 §6.7.2.1 Structure and union specifiers

¶3 A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.

¶18 As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply. However, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.

这篇关于指针和一阵列的差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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