2011-06-09 14 views
5

otra cuestión vinculada es Segmentation fault while using strcpy()?La inicialización de un puntero a una estructura

que tienen una estructura:

struct thread_data{  
    char *incall[10]; 
    int syscall arg_no;  
    int client_socket; 
}; 

¿Cómo inicializar un puntero a una estructura del tipo anterior, así como inicializar el puntero a la 10 cuerdas (incall []) dentro de la estructura.

Primero inicializo las cadenas y luego la estructura.

Gracias.

Una edición: Supongo que usé la palabra incorrecta y debería haber dicho allocate. En realidad, estoy pasando esta estructura como un argumento para los hilos. El número de hilos no es fijo y la estructura de datos enviada como argumento debe ser única para cada hilo y "hilo seguro", es decir, no puede ser cambiado por otros hilos.

+3

Esos son diez punteros a cadenas, no un puntero a 10 cadenas. Parece que te estás adelantando un poco ... – Potatoswatter

+0

¿Inicializar o asignar? –

Respuesta

10

Aquí está la respuesta a la pregunta que piense usted está preguntando:

/** 
* Allocate the struct. 
*/ 
struct thread_data *td = malloc(sizeof *td); 

/** 
* Compute the number of elements in td->incall (assuming you don't 
* want to just hardcode 10 in the following loop) 
*/ 
size_t elements = sizeof td->incall/sizeof td->incall[0]; 

/** 
* Allocate each member of the incall array 
*/ 
for (i = 0; i < elements; i++) 
{ 
    td->incall[i] = malloc(HOWEVER_BIG_THIS_NEEDS_TO_BE); 
} 

Ahora puede asignar cadenas a td->incall así:

strcpy(td->incall[0], "First string"); 
strcpy(td->incall[1], "Second string"); 

Idealmente, usted quiere comprobar el resultado de cada malloc para asegurarse de que se ha realizado correctamente antes de pasar a la siguiente cosa.

+0

He dado una edición. Probablemente usé la palabra "inicializar" de manera incorrecta. Debería haber sido "asignar" como dijiste –

1

Depende si necesita la variable sea temporal o no:

struct thread_data data; // allocated on the stack 
// initialize your data.* field by field. 

struct thread_data* data = malloc(sizeof (struct thread_data)); // allocated on the heap 
// initialize your data->* field by field. 

En ambos casos, usted tiene que asignar su primera estructura para poder acceder a sus campos.

1

Usted puede escribir algo como esto:

#define ARRAY_DIMENSION(a) (sizeof(a)/sizeof((a)[0])) 

void init_func(void) 
{ 
    struct thread_data arg_to_thread; 
    int i; 
    char buffer[100]; 

    buffer[0] = '\0'; 

    for (i = 0; i < ARRAY_DIMENSION(arg_to_thread.incall); i ++) 
    { 
     /* Do something to properly fill in 'buffer' */ 

     arg_to_thread.incall[i] = strdup(buffer); 
    } 
} 
1

creo malloc(sizeof(struct thread_data)); debería funcionar, ¿no es así?

+1

Este es un caso donde es posible que prefiera 'calloc' para obtener el comportamiento de inicialización cero porque establece los punteros de forma segura en NULL. Ayuda aún más si puede hacer que el número de syscall de valor cero y también algo seguro sea seguro. – dmckee

1

Aquí hay otra posibilidad. No está claro para qué quieres que se inicialicen los valores, por lo que esto simplemente saca un número del aire, lo que es casi seguro que está mal.

struct thread_data *td; 
int i; 
// allocate memory for the structure 
td = malloc(sizeof(struct thread_data)); 
// then allocate/initialize the char* pointers. It isn't clear 
// what you want in them ... pointers to existing data? Pre-allocated 
// buffer? This just allocates a fixed size buffer, 
for (i = 0; i < sizeof(td->incall)/sizeof(td->incall[0]); i++) 
    td->incall[i] = malloc(42); 
4

El struct initialiser correspondiente puede tener este aspecto:

struct thread_data a = { 
    .incall = {"a", "b", "c", "d", "e"}, 
    .arg_no = 5, 
    .client_socket = 3 
}; 

A continuación, puede asignar la dirección de este a un puntero:

struct thread_data *b = &a; 
+3

Si esto se hace dentro de una función, el '* b' terminaría señalando en algún lugar de la pila una vez que la función regrese? – TheMeaningfulEngineer

+1

Sí, pero siempre es responsabilidad del programador asegurarse de que ningún puntero siga apuntando a la memoria desde el marco de pila una vez que la función finalice. –

Cuestiones relacionadas