user-0 提问: c语言问题求助

回复:
user: user-1

user: user-0
content: 明白了，谢谢大神

user: user-2
content: malloc为指针开辟动态堆内存空间 ，并用free进行释放。malloc开辟的空间不会由系统自动释放，所以需要用户自己用free去释放它，否则会造成内存泄露，不过当程序运行结束后，系统也会将这些内存回收

user: user-2
content: char *strcpy( char *strDestination, const char *strSource ); strcpy第一个参数是一个指针，其内存必需在调用strcpy之前开辟，否则会出现指针越界访问

user: user-2
content: 你说的是strcpy吗？ 将后面参数的字符串数据复制到前面字符串中，以‘\0’结尾 malloc是开辟内存，并返回内存的首地址，不是复制内存。相当于我建一栋房子，告诉你地址，你就能通过我给你的地址找到访问它。sno[i]相当于一个地址函，记录内存的地址

user: user-0
content: 再请问下什么情况要用malloc开空间呢，如果不malloc直接stcrpy，就会崩溃

user: user-0
content: 引用 13 楼 ant2012 的回复:按照我贴的代码改，运行一下看看有没有问题  或者将pl->sno[i] = (char*)malloc(sizeof(char) * 10);改成 pl->sno[i] = (char*)malloc(sizeof(char) * pl->max);就能发挥m参数的作用了 好的，这个函数就是复制内存过去的吧？ 感谢大神帮助

user: user-2
content: 按照我贴的代码改，运行一下看看有没有问题  或者将pl->sno[i] = (char*)malloc(sizeof(char) * 10);改成 pl->sno[i] = (char*)malloc(sizeof(char) * pl->max);就能发挥m参数的作用了

user: user-0
content: 大概了解了问题，可是这样怎么改呀

user: user-2
content: 解决办法：  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复制插入的数据即可，而无需当场开辟内存空间

user: user-2
content: void insert(plist pl,int i,int x,char sno[10]) sno参数承接的是实参的地址，并没有发生数据的拷贝，即为x变量的地址，pl->sno[i]=sno;实际上是将x变量的地址给了sno。所以当再次插入值时，x变量的值被修改，从而sno[i]值也会修改

user: user-2
content: 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为其开辟堆空间

user: user-0
content: 引用 7 楼 ant2012 的回复:[quote=引用 6 楼 taoxin78 的回复:] 我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别  楼主好像没看懂我在3楼发的内容[/quote]  的确没太懂，malloc那部分是按照书上打的，书上没有写明是什么类型，写的是datatype，是泛泛的一种类型的意思我觉得，学生自学，不太清楚这部分内容，同样的写法不同的结果让我很诧异，小白求说的更简单一点

user: user-2
content: 引用 6 楼 taoxin78 的回复:我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别  楼主好像没看懂我在3楼发的内容

user: user-0
content: 我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别

user: user-2
content: 可能是字符串内存地址共用的问题，楼主可以把改好后的代码贴出来，方便我们去查错

user: user-0
content: 我是那个顺序表的提问者，可能之前的开辟空间有问题，但是我改了改并没有用 同是一个结构体下的int[]和char *[]，做出的反应不同，例如我输入 sno为aa name为4，他插入，查询打印的是aa 4，此时我再插入，比如插入在之前参数之后，bb 5，他查询打印的是 bb 4，bb 5，如果插入之前，就是bb 5，bb4，也就是说，数字int插入的是正确的，而输入的字符串，不正确，但是写法都是一样的啊

user: user-2
content: 楼主，你是不是前面出问题了 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中其它元素由于没有指向有效的内存地址，都处于野指针状态  总之，楼主好像对数组和指针的概念不是很清楚

user: user-0
content: 额，我的意思是，在红字部分的操作，如果是int[]型的进行循环传递就没问题，但是如果是字符串char *[]就会将后面的数据覆盖前面的，而不是一一替换，实在不理解操作一样结果不同是因为什么

user: user-3
content: 凑凑热闹，代码如下，详细过程参见 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; }