Структурная ссылка через символьную строку - PullRequest
0 голосов
/ 04 февраля 2012

Я пытаюсь понять основы структуры в C Пожалуйста, поймите Вот мой код: я запускаю блоки кода в Windows 7

#include<stdio.h>
struct xx
{
    int a;
    char x[10];
};

int main()
{


struct xx *p;
p->a=77;

    p->x[10] = "hello";
        printf("\n %d",p->a);
                  printf("\n %s ",p->x);
return 0;
    }

В строке, где я пытаюсь сделать печать p-> xпрограмма вылетает!Вторая проблема: верно ли, что когда я не инициализирую какие-либо целые числа структуры, они по умолчанию равны нулю, а строки, не инициализированные (символ звезды), по умолчанию равны нулю, если внутри структуры.*

Я получаю ошибку даже тогда !!Я даже пытался изменить

 char tem[] = "hello";

  p->x[]= tem[];

Тем не менее я получаю ошибку

p->x= tem[];

Эта строка также выдает ошибку даже это

 char *tmp = "hello";

  p->x= tem[];

даже это

 char *tmp = "hello";

  p->x[]= tem[];

даже эта строка является ошибкой

 char *tmp = "hello";

  p->x[10]= tem[];

Вы можете закрыть этот вопрос, но, пожалуйста, уточните меня!Как инициализировать массив символов в структуре

Ответы [ 3 ]

2 голосов
/ 04 февраля 2012

Вы должны выделить память для вашего struct, прежде чем пытаться его использовать, используя malloc():

struct xx *p = NULL;
p = malloc(sizeof(struct xx));
if (!p) { 
    fprintf(stderr, "could not allocate memory for pointer p\n");
    exit(-1);
}
p->a = 77;
...
free(p); /* do this when you no longer need pointer p */

Что касается доступа к x, этоЛучше всего скопировать строку, например, :

#include <string.h>
...
if (strncpy(p->x, "blahblah", 4))
    fprintf(stdout, "p->x: %s\n", p->x); /* p->x: blah */
else {
    fprintf(stderr, "could not copy string to p->x\n");
    exit(-1);
}

Попробуйте использовать strncpy(), где вы можете, так как ручное указание количества символов может помочь реализовать привычкупроверки границ, помогая избежать переполнения.

Например, давайте попробуем скопировать const char * в p->x, который оказывается длиннее того, что может содержать p->x:

#include <assert.h>

#define MAX_LENGTH 10

struct xx {
    int a;
    char x[MAX_LENGTH];
};
...
const char *foo = "blahblahblah";
assert(strlen(foo) < MAX_LENGTH); /* code should fail here */
if (strncpy(p->x, foo, strlen(foo) + 1))
    ...

Когда вы запустите это,assert() следует отключить:

Assertion failed: (strlen(foo) < MAX_LENGTH), function main, file test.c, line xyz.
Abort trap: 6

Как только foo сокращается до девяти или менее символов (вам нужен этот десятый символ для \0 терминатора, помните!) Код должен работать правильно.*

Так что используйте strncpy() и проверьте свои границы!

0 голосов
/ 04 февраля 2012

У вас есть пара проблем;

1) Вы путаете указатель на структуру с фактическим «экземпляром» структуры. p это указатель, но он ни на что не указывает, вам нужно сделать

p = malloc(sizeof(struct xx)); 

в строке после объявления, чтобы оно указывало на фактическую выделенную память. Вы должны использовать free() в этой памяти, как только вы закончили ее использовать.

Альтернативой было бы сделать p реальной структурой вместо указателя, изменив ее на

struct xx p;

(обратите внимание на отсутствие *) сделает p реальной структурой, и вы получите доступ к членам, используя p.x (доступ к структуре) вместо p-> x (доступ по указателю). Он также (в отличие от памяти, которую вы выделяете с помощью malloc) локально выделяется для вашей функции и автоматически «исчезает», как только выходит из области видимости, когда ваша функция существует.

Кроме того, строки в C также являются указателями, поэтому назначение «hello» чему-либо не приведет к автоматическому копированию строки. Вам нужно использовать strcpy(p->x, "hello");, чтобы скопировать данные в ваш массив символов.

Наконец, нет, почти ничего автоматически обнуляется в Си. Предположим, что вам нужно инициализировать все , и вы будете в безопасности и не должны помнить, что сделано автоматически, а что нет.

0 голосов
/ 04 февраля 2012

Ваша основная проблема в том, что указатель p , который должен указывать на структуру в памяти, не указывает на структуру.Указатель p просто содержит случайный мусор, и у вас нет структуры, на которую он мог бы указывать.

Самый простой способ исправить это - создать переменную структуры и разрешить p указывают на это:

struct xx the_actual_struct;
struct xx *p = &the_actual_struct;

Также нельзя присвоить строку, например поле x в структуре, с помощью обычного оператора присваивания =.Вам нужно использовать strcpy :

strcpy(p->x, "hello");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...