在n个结构的realloc'ed数组中跟踪指向struct i的指针?

时间:2016-02-14 13:46:22

标签: c arrays pointers struct

我malloc'ed一系列结构。在指向单独结构的指针的循环中,然后检查是否需要更多结构。如果是这样,则使用realloc来增加结构的数量。但是,由于realloc可能使用不同的内存块,因此必须将指向最后一个填充结构的旧指针更新到内存中的新位置。跟踪指针最后指向的数组结构的最佳方法是什么?下面的代码不起作用,它使用realloc()停止:旧的大小无效。为了清楚起见,我在分配后将检查留给了NULL。

#include <stdio.h>
#include <stdlib.h>

#define N 2
struct s 
{
  int a;
};
struct s **p;

int main() 
{
    struct s *q;
    int n = N;
    int i, j, m;

    p = malloc(n * sizeof(struct s *));
    for (i = 0 ; i < n ; i++)
        p[i] = malloc(sizeof(struct s));
    q = p[0];
    for (i = 0 ; i < 100 ; i++) 
    {
        if ((m = q - p[0] + 1) > n) 
        {
            printf("realloc at n %d\n", n);
            n *= 2;
            p = realloc(p, n * sizeof(struct s *));
            for (j = 0 ; j < n ; j++)
                p[j] = realloc(p[j], sizeof(struct s));
            q = p[m - 1];
        }
        q->a = i;
        q++;
    }
}

2 个答案:

答案 0 :(得分:1)

您分配了一个指针数组。使用标准C函数realloc时,它会将旧数组中已存在的值复制到新数组中。无需分配数组元素指向的新对象。

程序可以按以下方式查看

libraryDependencies ++= Seq(
  ws,
  "org.java-websocket" % "Java-WebSocket" % "1.3.0",
  "org.specs2" %% "specs2-core" % "3.7" % "test"
)

它的输出是

#include <stdlib.h>
#include <stdio.h>

#define N 2

struct s 
{
    int a;
};

int main( void )
{
    struct s **p;
    int n = N;    
    int i, j;

    p = malloc( n * sizeof( struct s* ) );

    for ( i = 0; i < n; i++ ) p[i] = malloc( sizeof( struct s ) );

    for ( i = 0; i < 100; i++ ) 
    {
        if ( i == n )
        {
            struct s **tmp = realloc( p, N * n * sizeof( struct s * ) );

            if ( !tmp ) break;

            p = tmp;
            n = N * n;

            for ( j = i; j < n; j++ ) p[j] = malloc( sizeof( struct s ) ); 
        }

        p[i]->a = i;
    }        

    for ( i = 0; i < ( n < 100 ? n : 100 ); i++ )
    {
        printf( "%2d ", p[i]->a );
        if ( ( i + 1 ) % 10 == 0 ) printf( "\n" );
    }        

    for ( i = 0; i < n; i++ ) free( p[i] );
    free( p );
}    

答案 1 :(得分:0)

更新指向realloc - ed块结尾的指针的最佳方法是不将该指针保留在第一位。不使用指针,而是使用数字偏移量,并根据需要在运行时计算指针。

这可以帮助您避免出现第一个逻辑问题:当您需要编写q++时,写malloc,指向struct - ed q = p[next]之后。

您的另一个问题是,当您将更多数据分配到p时,会倍增n

n *= 2;
p = realloc(p, n * sizeof(struct s *));
for (j = 0 ; j < n ; j++)
    p[j] = realloc(p[j], sizeof(struct s));

除了将realloc结果分配回p的常见问题之外,您realloc - struct - 进入整个数组,而不是{{1} } { - malloc元素到数组的上半部分:

n/2

最后,这个表达式for (j = n/2 ; j < n ; j++) p[j] = malloc(sizeof(struct s)); 没有意义:q - p[0]内部和q内部的指针不指向连续的内存区域,因为每个指针都与{{{1}分开分配。 1}}。因此,您不能对它们应用减法,并期望该值表示有意义的内容,例如指针之间的偏移。