Я где нужно использую такой способ и проблем не возникало. вот пример.
char *s = calloc ( 20, sizeof ( char * ) );
for ( int i = 0; i < 20; i++ ) {
s[i] = calloc ( 0, sizeof ( char ) );
}
где то в коде надо увеличить размер буфера.
int length = strlen ( buf );
s[i] = realloc ( s[i], sizeof ( char ) * length + 1 );
strncpy ( s[i], buf, length );
s[i][length] = 0;
Я делаю игру. и в игре сделал подобие сцены. можно в эту сцену добавить виджет на определенный слой и когда эта сцена будет рисовать виджеты, то будет начинать с самого младшего слоя. проблема здесь возникает что в какой то момент не делается realloc.
вот вывод в консоли.
всё не стал приводить.
вот хедер.
а вот код сцены.
#include "scene.h"
#include "button.h"
#include <stdlib.h>
void scene_init ( struct scene *sc ) {
sc->n = 0;
sc->obj = calloc ( 20, sizeof ( bd * ) );
sc->bs = calloc ( 20, sizeof ( bd ) );
sc->sclick = calloc ( 0, sizeof ( struct signal ) );
sc->sover = calloc ( 0, sizeof ( struct signal ) );
sc->count_click = 0;
sc->count_over = 0;
for ( int i = 0; i < 20; i++ ) {
sc->obj[i] = calloc ( 0, sizeof ( struct bdraw ) );
}
for ( int i = 0; i < 20; i++ ) {
sc->l[i] = -1;
sc->layers[i] = 0;
sc->bs[i].count = 0;
}
}
static int comp ( const void *p1, const void *p2 ) {
int pp1 = *( int * ) p1;
int pp2 = *( int * ) p2;
if ( pp1 > pp2 ) return 1;
if ( pp1 < pp2 ) return -1;
if ( pp1 == pp2 ) return 0;
}
static void find_layer ( struct scene *sc, const int layer ) {
int i = 0;
for ( i = 0; i < 20; i++ ) {
if ( sc->l[i] == -1 ) break;
if ( sc->l[i] == layer ) return;
}
sc->l[i] = layer;
sc->count_layer++;
qsort ( &sc->l[0], sc->count_layer, sizeof ( int ), comp );
#if 0
for ( int i = 0; i < sc->count_layer; i++ ) {
printf ( "%d\n", sc->l[i] );
}
printf ( "----------\n" );
#endif
}
void scene_add ( struct scene *sc, void *obj, int type, int layer ) {
int index = sc->layers[layer]++;
find_layer ( sc, layer );
printf ( "sc->layers[layer]: %d; layer: %d realloc start\n", sc->layers[layer], layer );
sc->obj[layer] = realloc ( sc->obj[layer], sizeof ( struct bdraw ) * sc->layers[layer] );
printf ( "realloc end\n" );
sc->bs[layer].type = type;
switch ( type ) {
case SCENE_BUTTON_RENDER:
sc->obj[layer][index].button = ( struct button * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "button index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
case SCENE_BOX_RENDER:
sc->obj[layer][index].box = ( struct box * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "box index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
case SCENE_SPRITE_RENDER:
sc->obj[layer][index].sprite = ( struct sprite * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "sprite index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
case SCENE_ACTOR_RENDER:
sc->obj[layer][index].actor = ( struct actor * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "actor index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
case SCENE_PROGRESS_RENDER:
sc->obj[layer][index].progress = ( struct progress * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "progress index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
case SCENE_FONT_RENDER:
sc->obj[layer][index].font = ( struct font * ) obj;
sc->obj[layer][index].type = type;
sc->bs[layer].count++;
printf ( "font index: %d layer: %d count: %d\n", index, layer, sc->bs[layer].count );
break;
}
}
void scene_render ( struct scene *sc ) {
for ( int layer = 0; layer < 20; layer++ ) {
if ( sc->l[layer] == -1 ) return;
int ll = sc->l[layer];
for ( int m = 0; m < sc->bs[ll].count; m++ ) {
switch ( sc->obj[ll][m].type ) {
case SCENE_BUTTON_RENDER:
{
struct button *btn = sc->obj[ll][m].button;
if ( btn->on ) button_render ( btn );
}
break;
case SCENE_BOX_RENDER:
{
struct box *box = sc->obj[ll][m].box;
if ( box->on ) box_render ( box );
}
break;
case SCENE_SPRITE_RENDER:
{
struct sprite *sp = sc->obj[ll][m].sprite;
if ( sp->on ) sprite_render ( sp );
}
break;
case SCENE_ACTOR_RENDER:
{
struct actor *act = sc->obj[ll][m].actor;
if ( act->is_single ) {
if ( act->on ) actor_render_single ( act );
}
else {
if ( act->on ) actor_render ( act );
}
}
break;
case SCENE_PROGRESS_RENDER:
{
struct progress *prg = sc->obj[ll][m].progress;
if ( prg->on ) progress_render ( prg );
}
break;
case SCENE_FONT_RENDER:
{
struct font *fnt = sc->obj[ll][m].font;
printf ( "fnt: %p\n", fnt );
if ( fnt->on ) font_render ( fnt );
}
}
}
}
}
void scene_signal_connect ( struct scene *sc, void *widget, const int type_of_signal, const int type_of_widget, void (*func) (void *widget, void *data), void *data ) {
switch ( type_of_signal ) {
case SCENE_SIGNAL_CLICK:
{
int index = sc->count_click++;
sc->sclick = realloc ( sc->sclick, sizeof ( struct signal ) * sc->count_click );
sc->sclick[index].widget = widget;
sc->sclick[index].func = func;
sc->sclick[index].data = data;
sc->sclick[index].type = type_of_widget;
}
break;
case SCENE_SIGNAL_OVER:
{
int index = sc->count_over++;
sc->sover = realloc ( sc->sover, sizeof ( struct signal ) * sc->count_over );
sc->sover[index].widget = widget;
sc->sover[index].func = func;
sc->sover[index].data = data;
sc->sover[index].type = type_of_widget;
}
break;
}
}
void scene_event_click ( struct scene *sc, const int x, const int y ) {
for ( int i = 0; i < sc->count_click; i++ ) {
struct signal *s = &sc->sclick[i];
switch ( s->type ) {
case SCENE_BUTTON_RENDER:
{
struct button *b = ( struct button * ) s->widget;
if ( x >= b->box->x && x <= b->box->x + b->box->box_width ) {
if ( y >= b->box->y && y <= b->box->y + b->box->box_height ) {
if ( b->on ) s->func ( s->widget, s->data );
return;
}
}
}
break;
}
}
}
void scene_event_over ( struct scene *sc, const int x, const int y ) {
for ( int i = 0; i < sc->count_over; i++ ) {
struct signal *s = &sc->sover[i];
switch ( s->type ) {
case SCENE_BUTTON_RENDER:
{
struct button *b = ( struct button * ) s->widget;
if ( x >= b->box->x && x <= b->box->x + b->box->box_width ) {
if ( y >= b->box->y && y <= b->box->y + b->box->box_height ) {
b->over = 1;
if ( b->on ) {
if ( s->func ) s->func ( s->widget, s->data );
}
return;
} else {
b->over = 0;
}
} else {
b->over = 0;
}
}
break;
}
}
}
void *scene_get_obj ( struct scene *sc, const char *name, const int layer ) {
int ll = layer;
for ( int m = 0; m < sc->bs[ll].count; m++ ) {
switch ( sc->obj[ll][m].type ) {
case SCENE_BUTTON_RENDER:
{
struct button *btn = sc->obj[ll][m].button;
if ( !strncmp ( btn->name, name, strlen ( name ) + 1 ) ) return btn;
}
break;
case SCENE_BOX_RENDER:
{
struct box *box = sc->obj[ll][m].box;
if ( !strncmp ( box->name, name, strlen ( name ) + 1 ) ) return box;
}
break;
case SCENE_SPRITE_RENDER:
{
struct sprite *sp = sc->obj[ll][m].sprite;
if ( !strncmp ( sp->name, name, strlen ( name ) + 1 ) ) return sp;
}
break;
case SCENE_ACTOR_RENDER:
{
struct actor *act = sc->obj[ll][m].actor;
if ( !strncmp ( act->name, name, strlen ( name ) + 1 ) ) return act;
}
break;
case SCENE_PROGRESS_RENDER:
{
struct progress *prg = sc->obj[ll][m].progress;
if ( !strncmp ( prg->name, name, strlen ( name ) + 1 ) ) return prg;
}
break;
case SCENE_FONT_RENDER:
{
struct font *fnt = sc->obj[ll][m].font;
if ( !strncmp ( fnt->name, name, strlen ( name ) + 1 ) ) return fnt;
}
default:
break;
}
}
return NULL;
}
void scene_layer_turn ( struct scene *sc, const int layer, const int on ) {
int ll = layer;
for ( int m = 0; m < sc->bs[ll].count; m++ ) {
switch ( sc->obj[ll][m].type ) {
case SCENE_BUTTON_RENDER:
{
struct button *btn = sc->obj[ll][m].button;
btn->on = on;
}
break;
case SCENE_BOX_RENDER:
{
struct box *box = sc->obj[ll][m].box;
box->on = on;
}
break;
case SCENE_SPRITE_RENDER:
{
struct sprite *sp = sc->obj[ll][m].sprite;
sp->on = on;
}
break;
case SCENE_ACTOR_RENDER:
{
struct actor *act = sc->obj[ll][m].actor;
act->on = on;
}
break;
case SCENE_PROGRESS_RENDER:
{
struct progress *prg = sc->obj[ll][m].progress;
prg->on = on;
}
break;
case SCENE_FONT_RENDER:
{
struct font *fnt = sc->obj[ll][m].font;
fnt->on = on;
}
default:
break;
}
}
}