2014-12-15 3 views
0

У меня есть функция, возвращающая char**.I. указатель на массив символов. Здесь я читаю файл в количестве каталогов для определенного целочисленного значения ind. Если он находит значение в файле, он должен вернуть имя каталога. Я попытался использовать статическое распределение, но это не поможет, потому что возвращение этих переменных приводит к неопределенному поведению. В моем случае я получаю все значения такими же, как имя последнего каталога. Вероятно, это происходит потому, что я читаю из выделенного системного стека. Затем я использовал динамическое выделение и Вот код, который я написал:Функция, возвращающая указатель на строку

//Global variable 
int found = 0; 

char** get_strings(int ind) 
{ 
FILE *fp; 
char filename[64]; 
char name[16]; 
//char *name; 
char **array; 
int i = 0, found = 0, l = 0; 
int val = 0; 

    char **array = (char **)malloc(10 * sizeof(char *)); 
for(l = 0; l < 10; l++) 
    array[l] = (char *)malloc(16 * sizeof(char)); 

    //name = (char *)malloc(16 * sizeof(char)); 

for(i=1;i<=10;i++) 
{ 
    snprintf(filename, sizeof(char) * 64, "/home/ben/dir%d/name", i); 
    fp = fopen(filename, "r"); 

    if(fp == NULL) 
    { 
      perror("Error opening file"); 
    } 
    fscanf(fp, "%d", &val); 
    fclose(fp); 
    //printf("value-%d is %d\n", i, val); 

    if (val != 0 && val == ind) 
    { 
     snprintf(name, sizeof(char) * 16, "dir%d", i); 

     printf("Dir %s is a has %d\n", name, ind); 
     strncpy(array[found],name, strlen(name)); 
     found++; 
    } 
} 
return array; 
} 

и я называю его основной функции как:

int i = 0; 
char **array; 
array = get_strings(1); 
for(i=0;i< found;i++) 
    printf("array[%d] = %s\n", i, array[i]); 

я получаю значение мусора на выходе. Может ли кто-нибудь помочь?

+0

'sizeof (char)' reduntant и всегда будет оцениваться до 1. Кроме того, вам не нужно прибегать к типу, чтобы преобразовать в/из 'void *' в C. Это неявно. – Qix

ответ

1

Думаю, что вы не должны использовать strncpy(). Используйте команду strcpy(). Попробуйте ... также выделите + 1 в malloc.

Причина: память, выделенная malloc, не была предварительно инициализирована ко всем нулям. Таким образом, ваши строки, вероятно, не завершены должным образом, и они будут переполняться при вызове printf. Дополнительный +1, я рекомендую просто хранить нулевой байт, который необходим в дополнение к 16 фактическим символам, которые вы хотите сохранить.

Кроме того, для (i = 1; i < = 10; i ++) неверно. цикл от 0 до < 10, а затем в вашем snprintf используйте i + 1.

EDIT: Кстати, есть функция strdup(), которая будет выделять строку. Для того, чтобы использовать его, я бы рекомендовал:

1/выделить ваш массив с:

char **array = calloc(10, sizeof(char *)); 

это будет предварительно инициализировать все члены в NULL, так что вы не должны предварительно выделить строки или положить NULL в слотах. Что делает его готовым:

2/копировать строки в с strdup(), если вы хотите хранить их:

if(conditions are ripe) 
    array[found++] = strdup(name); 

Итак, ваши петли будут идти от 0 до < найдено. Если вы выберете выделение массива массивов, вы получите только бесплатные звонки() в слотах от 0 до <.

+0

В этом случае он не имеет функциональных отличий, использует ли они 'strncpy' или' strcpy'. Они в основном передают 'strncopy' то, что' strcopy' передаст его. – Qix

+1

нет, он не будет завершен нулем. –

+0

Я не думаю, что есть проблема с циклом for. Я не использую его для массива. Это просто для изменения имени каталога и открытия файла. Я использую глобальную переменную 'found' для индексации массива. –

0

Вы выделение памяти для 10 строк:

malloc(10 * sizeof(char *)); 

... что означает, что действительные индексы массивов 0 до (включительно) 9. В частности, 10 не является допустимым индекс. Попробуйте настроить петли на

for(i=0;i<10;i++) 
+0

Это не единственная проблема, но, вероятно, ее причина. – Qix

+0

Я не знаю, что цикл for имеет отношение к индексам массива. Я не использую цикл для доступа к элементам массива. –

+0

@BenWilliams Вы написали, что вы выполняете 'for (i = 1; i <= 10; i ++) printf (" array [% d] =% s \ n ", i, array [i]);' в вашей основной функции , а 'array' - массив, возвращаемый вашей функцией. –

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