为什么我无法使用以下代码显示字符串?

时间:2014-02-03 20:35:15

标签: c string

如果我放了"&"在printf中,它至少会打印国家的名称,它会崩溃。否则,它会立即崩溃。我的猜测是,for循环有问题。如果我错了,请告诉我。

 //Implementation file//
 #include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 struct list
 {
     char *item;
     int length;
 };
 typedef struct list LIST; //aliasing the structure//
 LIST *create()      //constrcutor//
 {
     LIST *L = (LIST*)malloc(sizeof (LIST));
     L->length=0;
     return L;
 }
 void insert(LIST* L, char *newitem)
 {
     L->item=(char*)malloc(sizeof(char));
     strcpy(L->item, newitem);
     (L->length)++;
 }
 void display(LIST *L)
 {
     int i;
     for(i=0;i<(L->length);i++)
     {
         printf("Elements are: %s\n", L->item[i]);

     }
 }
 int main ()
 {
     LIST *L;
     L=create();
     insert(L, "America");
     insert(L, "Brazil");
     display(L);
     free(L->item);
     free(L);
     return 0;
 }

5 个答案:

答案 0 :(得分:3)

L->item=(char*)malloc(sizeof(char));
strcpy(L->item, newitem);

您只分配一个字节,但是您尝试将整个字符串复制到L->item,从而导致未定义的行为。这应该是:

L->item=malloc(sizeof(char)*(strlen(newitem)+1));
strcpy(L->item, newitem);

您还调用函数insert两次,这将为L->item分配新内存并将指针松散到先前分配的空间 - &gt;内存泄漏。你应该添加列表元素而不是一直覆盖第一个元素,参见@DavidKernin的回答。

答案 1 :(得分:3)

您的代码中存在巨大错误:插入新元素时,您应该创建新的列表元素并初始化它。

使用功能

 void insert(LIST* L, char *newitem)
 {
     L->item=(char*)malloc(sizeof(char));
     strcpy(L->item, newitem);
     (L->length)++;
 }

这样叫:

 insert(L, "America");
 insert(L, "Brazil");

你总是为 length 编写相同的元素并分配新内存(甚至没有使用/存储指向旧分配的指针...这就丢失了! )。

你应该做类似的事情:

//Implementation file//
 #include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 struct list
 {
     char *item;
     struct list* next;
 };
 typedef struct list LIST; //aliasing the structure//
 LIST *create()      //constrcutor//
 {
     LIST *L = (LIST*)malloc(sizeof (LIST));
     L->next = 0;
     return L;
 }
 LIST* insert(LIST* L, char *newitem)
 {
     L->item=(char*)malloc(sizeof(char)*strlen(newitem));
     strcpy(L->item, newitem);
     LIST *newL = (LIST*)malloc(sizeof (LIST));
     newL->next = 0;
     L->next = newL;
     return newL;
 }
 void display(LIST *L)
 {
     int i;
     for(i=0; L->next != 0;L = L->next) // Assumes there's at least 1 item
     {
         printf("Elements are: %s\n", L->item);
     }
 }
 int main ()
 {
     LIST *startElement;
     startElement=create();
     LIST *lastElement = insert(startElement, "America");
     lastElement = insert(lastElement, "Brazil");
     display(startElement);
     // Free all memory.. exercise :)
     return 0;
 }

以交互方式试用:http://ideone.com/n8tRtv

否则链接列表的目的将完全失败..谁想要一个在插入新元素时丢失以前元素的列表?

请注意上面的代码

  1. 不释放内存

  2. 始终假设列表中至少有一个项目

  3. 如果你想要一个完整的代码,那么......修复它。如果您了解它是如何工作的,那么完全修复它应该是相当可行的。祝你好运!

答案 2 :(得分:1)

您的代码的以下修改将允许您插入字符串并打印它们。既然这就是你所要求的,那就是你将得到的。如果您在编写此代码时考虑到某种特定的数据结构(可能是链表等),请指明。

struct list
{
    char **item;
    int length;
};

struct list现在包含一个指向char *的指针数组。

LIST *create()
{
    LIST *L = (LIST*)malloc(sizeof (LIST));
    L->item = (char **)malloc(sizeof(char *));
    L->length=0;
    return L;
}

这将是你的列表malloc的正确方法。

void insert(LIST* L, char *newitem)
{
    L->item[L->length] = (char *)malloc(sizeof(char *));    
    strcpy(L->item[L->length++], newitem);
}

将malloc插入一个新的char指针,该指针位于char指针数组的末尾。复制插入的字符串并增加长度。

不要忘记免费()!

答案 3 :(得分:0)

printf语句中的说明符不正确。您使用的%s需要char*,但您传递的是char。因此,printf实现将字符值视为地址并立即运行到无效内存并崩溃

要解决此问题,您需要切换为使用%c

printf("Elements are: %c\n", L->item[i]);

请注意,这会导致每个char在不同的行上打印出来。很可能你想要类似下面的东西

printf("Elements are: %s\n", L->item[i]);
int i;
for(i=0;i<(L->length);i++)
{
  printf("%c", L->item[i]);

}
printf("\n");

请注意,如果您的意图是让item成员为空终止char*,那么最简单的解决方法是执行以下操作

printf("Elements are: %s\n", L->item);

答案 4 :(得分:0)

L->item=(char*)malloc(sizeof(char));

是代码中的一个问题