2013-10-10 3 views
0

Я работаю над заданием и столкнулся с проблемой. Что касается меня, и из того, что я узнал, следующий код должен быть правильным, но он не работает. В основном то, что я пытаюсь, копирует строковое значение в элемент переменной структуры, является частью массива, переданного в метод как указатель. Что мне не хватает?Изменение значений в элементах массива структур

typedef struct 
{ 
    char * name; //variable in struct I am trying to access 
} Struct; 

void foo(Struct * arr) //array of Structs passed into function as a pointer 
{ 
    int i = 0; 
    while(i++ < 2)  
    { 
     arr[i].name = malloc(sizeof(char *)); //assigning memory to variable in each Struct 
     arr[i].name = strdup("name"); //copying "name" to variable in each Struct 
     printf("C - %s\n", arr[i].name); //printing out name variable in each Struct 
    } 
} 

main() 
{ 
    Struct * arr; //defining pointer 
    arr = calloc(2, sizeof(Struct)); //allocating memory so pointer can hold 2 Structs 
    foo(arr); //calling function foo passing pointer into function 
    return 0; 
} 

Этот код компилируется и запускается, однако он не выполняет то, что он предназначен для выполнения. Простите меня, если это что-то тривиальное. Я новичок в языке C

+1

'ЬурейиЕ структуры Struct' очень, * очень * *** очень плохо Идея. *** –

+0

Я использовал «Struct», чтобы сделать это очевидным при чтении, что я использую указатель как массив структур – etienz

+0

1. базовый тип массива не имеет значения. 2. Но это видно из декларации, это небольшой фрагмент кода. 3. Если вы хотите сделать его явным в любом случае, не делайте typedef и используйте ключевое слово 'struct', как в' struct Foo array [100]; '. Не вызывайте путаницу. Довольно пожалуйста. –

ответ

2

Два вопроса:

  1. while(i++ < 2) Эта строка изменяет значение i как только он проверяет его, так что ваше тело цикла не будет таким же, как он был установлен.
  2. arr[i].name = strdup("name"); перезаписывает значение указателя .name, вызывая утечку памяти из памяти, которую вы malloc() 'ранее.
-1

Это не отвечает на ваш вопрос сразу, но решает проблему с большой, чтобы положить в комментарий ...
Дополнительный выпуск: Вы, вероятно, не намерены выделять только (символ *) на сумму памяти для переменной, предназначенной для хранения как минимум «имени». Изменить;

arr[i].name = malloc(sizeof(char *));

к:

arr[i].name = malloc(sizeof(char)*strlen("name")+1); // + 1 для '\ 0'

или еще лучше, использовать char *name="name";, то:

arr[i].name = malloc(sizeof(char)*strlen(name)+1);

Еще более общий (и лучше):

char *name; 

name = malloc(strlen(someInputString)+1); 
//do stuff with name... 
free(name); 

Теперь вы можете выделить name любой длины, необходимой на основании длины someInputString.

[EDIT] Etienz, я хотел бы обратиться еще одну вещь, упоминается на @ Н2СО3 выше, но на самом деле не объяснил, что я думаю, что может быть полезным для Вас:
Что касается Вашего желания иметь место для двух структур, потому что вы typedef'd свою структуру, вы можете просто сделать что-то вроде этого: (но я собираюсь изменить имя, которое вы использовали из Struct в NAME :) Все дело в том, что когда структура создается как массив, вам не нужно использовать calloc или malloc для создания пространства для них, это делается, как показано ниже ...

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

typedef struct{ 
    char *name; 
}NAME; 
//use new variable type NAME to create global variables: 
NAME n[2], *pN; //2 copies AND pointer created here 
//prototype func 
int func(NAME *a); 
int main() 
{ 
    pN = &n[0]; //pointer initialized here 
    func(pN); //pointer used here (no malloc or calloc) 
    printf("name1 is %s\nname 2 is %s", pN[0].name, pN[1].name); 
    return 0; 
} 

int func(NAME *a) 
{ 
    char namme1[]="andrew"; 
    char namme2[]="billebong"; 
    //You DO have to allocate the members though 
    a[0].name = malloc(strlen(namme1)+1); 
    a[1].name = malloc(strlen(namme2)+1); 

    strcpy(a[0].name, namme1); 
    strcpy(a[1].name, namme2); 
    return 0; 
} 
+1

sizeof (char), а не sizeof (char *). плюс 1 –

+0

Да, важно, и пропустил это. Спасибо – ryyker

+0

По-прежнему нужен +1 для терминатора. –

1

Продление на 2 указал правильно уже

arr[i].name = strdup("name"); 

Даже если вы используете следующие вместо выше,

strcpy(array[i].name, "name"); 

вы не выделили достаточно байт для хранения строки т.е. это неверно

arr[i].name = malloc(sizeof(char *)); 
// even if pointer is 8 byte here, concept isn't right 

Должно быть что-то вроде

arr[i].name = malloc(strlen("name")+1); 
// or MAX_SIZE where it is greater than the possible "name". 

Или еще лучше, удалить таНос вообще, strdup заботится о выделении самой

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