2013-05-30 5 views
2

Я искал и пытался запускать простые тестовые программы, но я до сих пор не могу понять это:Динамическое распределение указателей на массивы

Можно ли, в чистом C, чтобы выделить указатель динамически, что точки к массиву?

Что я хотел бы сделать, это скопировать строку в массив char [20], но количество этих массивов символов неизвестно. Переменная Заявляю это

char (*value)[20] 

Из того, что я понимаю, что это указатель на массив из 20 символов, который является то, что мне нужно

Однако, как я выделить память для этой переменной? Как я могу сделать это динамически, в котором я не знаю количество символов [20], которое будет существовать? Неужели я думаю, что это решение моей проблемы с дизайном?

Спасибо.

+0

'для копирования строки в char [20] array' - одна строка в один массив? Почему вам нужно много массивов? – kotlomoy

+0

Я сформулировал это плохо. Что происходит, я получаю сообщения Netlink от ядра. Каждый раз, когда я получаю сообщение, он возвращает строку. Я хочу сохранить эту строку (длиной 20), но количество раз, когда ядро ​​отправит сообщение, неизвестно. Поэтому потребность в динамическом распределении массива известной длины ... если это имеет смысл. – justynnuff

+0

'выделить указатель, указывающий на массив' - что вы имеете в виду? Вы выделяете память, а не указатель. Итак, какая память вам нужна? Для указателя или массива? – kotlomoy

ответ

1

Если вы хотите массив, который растет в размерах, у вас нет другого выбора, кроме как динамически выделять память, таким образом, например, при условии, что вы знаете все ваши строки будут иметь ровно 20 символов:

#define STR_SIZE 20 
char* values = NULL; 
int nb = 0; 

... 

// Called every time a string is received 
// Here valuesPtr is a char** since we want to change values 
void appendStr(char** valuesPtr, int* nb, char* string) { 
    if (*nb == 0) { // First item 
     *valuesPtr = malloc(STR_SIZE); 
    } else { // The size of the array changes : realloc it 
     *valuesPtr = realloc(*valuesPtr, STR_SIZE * (*nb + 1)); 
    } 

    if (*valuesPtr == NULL) { // Something went wrong ! 
     perror("malloc/realloc"); 
     exit(1); 
    } 

    // Copy the new string at the right place 
    memcpy(*valuesPtr + STR_SIZE * (*nb), string, STR_SIZE); 
    *nb++; 
} 

В остальной части кода, доступ к п-ю строку выполняется следующим образом:

values + (STR_SIZE * nb) 
+0

Я n00b, поэтому я не могу +1, но это решение, которое я ищу. Я думал, что будет более эффективный способ использования указателя на массив символов, а не только указатель на указатель, но я полагаю, что нет.Спасибо :) – justynnuff

0

Вот пример, который записывает постоянную строку в массив массивов, на которые указывает значение num_arrays раз.

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

void func(int num_arrays) 
{ 
    const char* s = "A string"; 
    char (*value)[20]; 
    value = (char (*)[20]) malloc(sizeof(*value) * num_arrays); 
    int i; 
    for(i = 0; i < num_arrays; i++) { 
    strncpy(value[i],s,20); 
    } 
    for(i = 0; i < num_arrays; i++) { 
    printf("%s\n", value[i]); 
    } 
} 
+0

Да, но 'num_arrays' неизвестно, поэтому я не могу« malloc »весь блок памяти в начале. Я думаю, что мне нужно «malloc (sizeof (* value))' для первого значения char [20] и использовать некоторую арифметику указателя для 'malloc' еще одного 20-символьного фрагмента памяти позже. Но я не уверен, что делать. Что-то вроде 'value + sizeof (* value) = malloc (sizeof (* value))', но это не работает. – justynnuff

1

Обычно вы будете использовать массив строк:

char *strings[256]; // or use malloc/realloc but 256 pointers is OK 
int cnt = 0; 
void add_string(const char *s) { 
    strings[cnt] = (char*)malloc(strlen(s)+1); // or 21 
    cnt++; 
    // you can also do circular buffers 
} 
+0

Это решение, но я вижу это так: я знаю, сколько символов содержит мои строки, но не сколько строк будет. Это решение предполагает, что вы знаете, сколько строк будет (256), но не количество символов в каждом. – justynnuff

+0

это только для того, чтобы показать вам, что вы можете использовать круговой буфер или динамический массив 'char *', и вам не нужен массив 'char [20]' s. – perreal

Смежные вопросы