我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++;
}
}
答案 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}}。因此,您不能对它们应用减法,并期望该值表示有意义的内容,例如指针之间的偏移。