c语言问题求助

taoxin78 2015-07-28 04:52:40
c语言,用的vc,想要的是做个顺序表,现在插入信息出问题了,之后输入的信息会盖掉之前所有的,用的结构体,这之中有int的name和字符串的sno,int型的没问题,但是字符串类型的先插入a,再插入b,b会盖掉a,显示的为b b,但是int的显示的就正常,算法写的结构都是一样的,求大神帮助,代码如下,红字部分为插入的算法,写的一样但是类型不同结构不同,小白求回答的详细点




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


struct list
{
int max;
int n;
int name[100];
char *sno[100];
};
typedef struct list *plist;
//创建一个空的顺序表,最大值为m。n为0
plist create(int m)
{
plist a=(plist)malloc(sizeof(struct list));
if(a!=NULL)
{
a->name[100]=(int )malloc(sizeof(int)*m);
a->sno[10]=(char *)malloc(sizeof(char)*m);
if(a->name&&a->sno)
{
a->max=m;
a->n=0;
printf("success to create\n");
return a;
}
else
{
free(a);
printf("free!");
}
}
else
printf("failed to create!");
return NULL;


}
//查询一个表是否为空表
int check(plist pl)
{
if(pl->n==0)
{
printf("empty\n");
return 0;
}
printf("not empty\n");
return 1;
}

//插入一个信息到顺序表,插入到第i个元素之前
void insert(plist pl,int i,int x,char sno[10])
{

int q;
if(pl->n<i)
{
printf("input error\n");
//return pl;
}
else
{

for(int q=pl->n-1;q>=i;q--)
{
pl->name[q+1]=pl->name[q];
pl->sno[q+1]=pl->sno[q];

}
pl->n++;
pl->name[i]=x;
pl->sno[i]=sno;
}

//return pl;

}

int visit(plist pl)
{
int flag=-1;
int i;
flag=check(pl);
if(!flag)
return 0;
else
{
for(i=0;i<pl->n;i++)
{
printf("%d:%d\n",i,pl->name[i]);
printf("%d:%s\n\n",i,pl->sno[i]);
}
}

}

void main()
{
list l;
plist pl;
char x[10];//存放姓名,方便输入,字符串
int loc=-1;//选择插入位置,插入在该参数之前
int id=-1;//id信息
int temp=0;
pl=create(10);
check(pl);


while(1)
{
printf("please press your name:\n");
scanf("%s",&x);
printf("press you id:");
scanf("%d",&id);
printf("please press which number you want put before:");
scanf("%d",&loc);
insert(pl,loc,id,x);
visit(pl);
}



/* list l;
int i=0;
plist pl; pl=create(10);
pl->sno[i]="tao";
i++;
pl->sno[i]="xin";
i++;
pl->sno[i]="cool";
pl->n=3;
visit(pl);*/
}




...全文
416 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
kuankuan_qiao 2015-07-30
  • 打赏
  • 举报
回复
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
明白了,谢谢大神
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
malloc为指针开辟动态堆内存空间 ,并用free进行释放。malloc开辟的空间不会由系统自动释放,所以需要用户自己用free去释放它,否则会造成内存泄露,不过当程序运行结束后,系统也会将这些内存回收
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
char *strcpy( char *strDestination, const char *strSource ); strcpy第一个参数是一个指针,其内存必需在调用strcpy之前开辟,否则会出现指针越界访问
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
你说的是strcpy吗? 将后面参数的字符串数据复制到前面字符串中,以‘\0’结尾 malloc是开辟内存,并返回内存的首地址,不是复制内存。相当于我建一栋房子,告诉你地址,你就能通过我给你的地址找到访问它。sno[i]相当于一个地址函,记录内存的地址
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
再请问下什么情况要用malloc开空间呢,如果不malloc直接stcrpy,就会崩溃
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
引用 13 楼 ant2012 的回复:
按照我贴的代码改,运行一下看看有没有问题 或者将pl->sno[i] = (char*)malloc(sizeof(char) * 10);改成 pl->sno[i] = (char*)malloc(sizeof(char) * pl->max);就能发挥m参数的作用了
好的,这个函数就是复制内存过去的吧? 感谢大神帮助
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
按照我贴的代码改,运行一下看看有没有问题 或者将pl->sno[i] = (char*)malloc(sizeof(char) * 10);改成 pl->sno[i] = (char*)malloc(sizeof(char) * pl->max);就能发挥m参数的作用了
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
大概了解了问题,可是这样怎么改呀
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
解决办法: a->name[100]=(int )malloc(sizeof(int)*m); a->sno[10]=(char *)malloc(sizeof(char)*m); if(a->name&&a->sno) { a->max=m; a->n=0; printf("success to create\n"); return a; } else { free(a); printf("free!"); } 改成 a->max=m; a->n=0; printf("success to create\n"); return a; 其它代码无意义,不可能到达 void insert(plist pl,int i,int x,char sno[10])中 pl->sno[i]=sno; 改为 pl->sno[i] = (char*)malloc(sizeof(char) * 10); strcpy(pl->sno[i], sno); 不过这样以来,create函数的参数m就没胡意义,如果要想其发生作用,可以在create对所有sno数组元素开辟内存空间,然后在insert函数中,只需strcpy复制插入的数据即可,而无需当场开辟内存空间
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
void insert(plist pl,int i,int x,char sno[10]) sno参数承接的是实参的地址,并没有发生数据的拷贝,即为x变量的地址,pl->sno[i]=sno;实际上是将x变量的地址给了sno。所以当再次插入值时,x变量的值被修改,从而sno[i]值也会修改
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small. 说得通俗点,malloc是为指针开辟空间用的,因为指针在定义的时候,系统不会为其开辟内存空间。所以所有指针的大小都是机器字长的大小 (32位机的指针大小为4个字节)。指针变量存放的是其它变量的地址,malloc为指针开辟一个堆内存,此时指针的值为开辟内存的首地址。 void *malloc( size_t size ); malloc返回的是一个void指针,在使用malloc为各种类型的指针变量开辟空间时需要对其返回值进行强制转换 如:int *pi = (int*)malloc(sizeof(int) * n); char *pc = (char*)malloc(sizeof(char) * n); 由于楼主定义的name是表态数组,不是指针,系统已经在定义时为其开辟了栈地址空间,不需要用malloc为其开辟堆空间
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
引用 7 楼 ant2012 的回复:
[quote=引用 6 楼 taoxin78 的回复:] 我把对于结构体malloc的那两条指令直接注释掉,他依然能跑,没有任何区别
楼主好像没看懂我在3楼发的内容[/quote] 的确没太懂,malloc那部分是按照书上打的,书上没有写明是什么类型,写的是datatype,是泛泛的一种类型的意思我觉得,学生自学,不太清楚这部分内容,同样的写法不同的结果让我很诧异,小白求说的更简单一点
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
引用 6 楼 taoxin78 的回复:
我把对于结构体malloc的那两条指令直接注释掉,他依然能跑,没有任何区别
楼主好像没看懂我在3楼发的内容
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
我把对于结构体malloc的那两条指令直接注释掉,他依然能跑,没有任何区别
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
可能是字符串内存地址共用的问题,楼主可以把改好后的代码贴出来,方便我们去查错
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
我是那个顺序表的提问者,可能之前的开辟空间有问题,但是我改了改并没有用 同是一个结构体下的int[]和char *[],做出的反应不同,例如我输入 sno为aa name为4,他插入,查询打印的是aa 4,此时我再插入,比如插入在之前参数之后,bb 5,他查询打印的是 bb 4,bb 5,如果插入之前,就是bb 5,bb4,也就是说,数字int插入的是正确的,而输入的字符串,不正确,但是写法都是一样的啊
二班的码农 2015-07-29
  • 打赏
  • 举报
回复
楼主,你是不是前面出问题了 a->name[100]=(int )malloc(sizeof(int)*m); 开辟m个整形的int型的连续内存给name数组中下标值为100的元素。 1. 下标值100已经越界,name是一个静态数组,其长度为100,下标值范围为0~99。 2. name是一个静态数组,其元素也是普通int型变量,当实例化一个结构体对象时,即楼主plist a=(plist)malloc(sizeof(struct list));操作系统已经为其开辟了栈空间,无需在通过malloc给其某个元素开辟动态堆空间。 3. 此时name[100](可能已经是sno中的元素)存放的是由malloc开辟的m个连续内存的首地址 a->sno[10]=(char *)malloc(sizeof(char)*m); sno是一个指针数组,即sno是一个静态数组,只不过其元素是一个字符型指针 以上这句代码的意思是为sno第11个元素(即下标值为10)开辟一个一个由m个char型组成的内存空间,sno[10]存放的是开辟空间的首地址。然而sno中其它元素由于没有指向有效的内存地址,都处于野指针状态 总之,楼主好像对数组和指针的概念不是很清楚
taoxin78 2015-07-29
  • 打赏
  • 举报
回复
额,我的意思是,在红字部分的操作,如果是int[]型的进行循环传递就没问题,但是如果是字符串char *[]就会将后面的数据覆盖前面的,而不是一一替换,实在不理解操作一样结果不同是因为什么
lazying_bird 2015-07-29
  • 打赏
  • 举报
回复
凑凑热闹,代码如下,详细过程参见 http://blog.csdn.net/a_flying_bird/article/details/47132415

/*
see: http://bbs.csdn.net/topics/391091587
*/

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

struct node
{
    int max_count;
    int current_count;
    int id[100];
    char *name[100];
};

typedef struct node *pnode;

//创建一个空的顺序表,最大值为m。n为0
pnode create(int max_count)
{
    pnode node = (pnode)malloc(sizeof(struct node));
    if (NULL == node) {
        printf("failed to create!");
        return NULL;
    }
    
    node->max_count = max_count;
    node->current_count = 0;
    printf("success to create\n");
    
    return node;
}

//查询一个表是否为空表
int is_empty(pnode pnode)
{
    if (pnode->current_count == 0) {
        //printf("empty\n");
        return 1;
    }

    //printf("not empty\n");
    return 0;
}

//插入一个信息到顺序表,插入到第index个元素之前
void insert(pnode pnode, int index, int id, char name[10])
{
    if (index < 0 || index > pnode->current_count) index = pnode->current_count;
    
    for(int q = pnode->current_count - 1; q >= index; q--) {
        pnode->id[q + 1] = pnode->id[q];
        pnode->name[q + 1] = pnode->name[q];
    }
    
    pnode->current_count++;
    pnode->id[index] = id;
    //pnode->name[index] = strdup(name); #MinGW's error
    pnode->name[index] = (char*)malloc(sizeof(char) * sizeof(strlen(name) + 1));
    if (NULL == pnode->name[index]) {
        printf("malloc failed.\n");
    } else {
        strcpy(pnode->name[index], name);
    }
    
    //return pnode;
}

int visit(pnode pnode)
{
    int i;
    
    if (is_empty(pnode)) return 0;
    
    for (i = 0; i < pnode->current_count; i++) {
        printf("%d:[%d, %s] ", i, pnode->id[i], pnode->name[i]);
    }
    
    printf("\n");
}

void delete(pnode pnode)
{
    int i;
    for (i = 0; i < pnode->current_count; i++) {
        free(pnode->name[i]);
        pnode->name[i] = NULL;
    }
    
    pnode->current_count = 0;
}

static void test1()
{   
    pnode pnode;
    char buffer[1024]; // Assume the input string will not exceed 1024.
    char name[1024];
    int loc = -1;
    int id = -1;
    int max_count = 10;
    int current_count = 0;
    pnode = create(max_count);
    
    if (NULL == pnode) return;
    
    while(1) {
        printf("Please enter: [name, id, index]. Enter directly to exit.\n");
        
        int index = 0;
        for (; (buffer[index] = getchar()) != '\n' && index < 1024; index++) {
            //printf("index=%d, buffer[%d]=0x%02x\n", index, index, buffer[index]);
        }
        
        //printf("index=%d\n", index);
        
        if (index == 0) {
            break;
        }
        
        //printf("User's input: %s\n", buffer);
        
        if (3 != sscanf(buffer, "%s %d %d", &name, &id, &loc)) {
            printf("Error input. The input should be, e.g., \"John 35 0\"\n");
            continue;
        }
        
        insert(pnode, loc, id, name);
        
        visit(pnode);
        
        current_count++;
        if (current_count == max_count) {
            printf("Now is the max count! Stop automatically!\n");
            break;
        }
    }
    
    delete(pnode);
}

int main()
{
    test1();
    
    return 0;
}
加载更多回复(1)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧