我正在尝试编写一个单独的程序,该程序调用一个函数来为一定数量的"学生"动态分配内存。结构
我的主程序太大而不能搞乱,所以我创建了一个较小的程序来帮助我更轻松地弄清楚我在做什么:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "memtest.h"
void structMemInit(myName **);
int main(void){
myName *myNameIs;
structMemInit(&myNameIs);
printf("%s\n", myNameIs[1].name);
return 0;
}
void structMemInit(myName **myNameIs){
*myNameIs = (myName *) calloc(5, sizeof(myName));
if(myNameIs == NULL){
printf("allocating memory didn't work!\n");
exit(1);
}
else if(myNameIs != NULL)
(*myNameIs)[1].name = "Zach";
}
memtest.h文件是:
typedef struct{
char *name;
}myName;
以上所有程序都试图将指向结构的指针传递给函数&#34; structMemInit&#34;并为结构分配干净的空间。然后看看它是否有效,我将变量char设置为名称。完成所有这些后,您将退出该功能并返回main。然后我在结构中打印名称以显示它有效。
运行时,程序总是会出现段错误。
如果您想知道为什么我有一个单独的.h文件,我的实际程序要大得多,并且有几个全局声明的结构,我的教师要求我为这些结构保留一个单独的.h。
谢谢! 扎克
答案 0 :(得分:1)
如果你坚持传递指针,它应该是引用,所以它是指针的指针,因为函数itslef将修改指针中的地址。
如果你的函数返回指针,你会好得多。
//function for allocating the memory
myName *structMemInit(void)
{
myName *myNameIs = (myName *)calloc(1, sizeof(myName));
if (myNameIs == NULL) {
printf("allocating memory didn't work!\n");
exit(1);
} else { // don't repeat the negation of the condition
myNameIs->name = "Zach"; // No need for \0, it's automatic
return myNameIs;
}
}
//Usage
myName *myNameIs = structMemInit();
BTW int main(void)
而非int main()
。
答案 1 :(得分:1)
在我回答之前,我应该说我不是很精通C,我是一名C ++程序员,所以下面可能会有一些语法错误。但是,希望我的观点足以让任何错误变得非常重要。
您遇到段错误的原因是您将指针作为参数传递给函数时误解了发生的事情。
想象一下,例如,您的计划如下:
int main(void){
int i;
setInteger(i);
printf("%d\n", i);
return 0;
}
void setInteger(int n){
n = 12;
}
在这种情况下,您可以清楚地看到输出将是未定义的,因为变量i
未初始化,并且按值传递给setInteger
。当函数返回时,对n
的任何更改都不会传回i
。
如果程序被替换为
int main(void){
int i;
setInteger(&i);
printf("%d\n", i);
return 0;
}
void setInteger(int *n){
*n = 12;
}
然后i
输出的值将为12
。
同样的事情发生在您的程序中,您将指针按值传递。
如果您想通过引用传递,则需要执行以下操作:
int main(void){
myName *myNameIs;
structMemInit(&myNameIs); // pass the address of your pointer
printf("%s\n", myNameIs->name);
return 0;
}
//function for allocating the memory
void structMemInit(myName **myNameIs){ // argument is pointer-to-pointer
*myNameIs = (myName *) calloc(1, sizeof(myName)); // dereference pointer to get underlying pointer
if(*myNameIs == NULL){
printf("allocating memory didn't work!\n");
exit(1);
}
else{
*myNameIs->name = "Zach";
}
}
不幸的是,这不是问题的结束。虽然您已为myName
对象分配了内存,但尚未为字符数组分配内存。
要返回字符串“Zach”,您需要执行以下操作:
*myNameIs->name = (char*)malloc(5*sizeof(char)); // need extra char for \0
strcpy(*myNameIs->name, "Zach");
答案 2 :(得分:-1)
请注意:
typedef struct{
char name[20];
} myName;
不同于:
typedef struct{
char *name;
} myName;
在第二种形式中,您没有为字符串分配任何空间。你只是为指针分配空间。
以下是程序的运行版本。如果您想使用strcpy(p->name, "Zach");
,则需要在结构中使用char name[20];
。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
// char name[20];
char *name;
} myName;
myName *structMemInit();
int main(){
myName *myNameIs;
myNameIs = structMemInit();
if (myNameIs)
printf("%s\n", myNameIs->name);
return 0;
}
//function for allocating the memory
myName *structMemInit(){
myName * p = (myName *) malloc(sizeof(myName));
if (p == NULL){
fprintf(stderr, "allocating memory didn't work!\n");
} else {
fprintf(stderr, "allocating %d memory work!\n", sizeof(myName));
// strcpy(p->name, "Zach");
p->name = strdup("Zach");
}
return p;
}