我正在为代码创建函数,并且代码使用该函数输出到文件指针,例如
public static Node getFirst(Node list)
{
if (list == null)
{
System.out.println("Error!");
System.exit(1);
}
return MyLinkedList.first;
}
这是我到目前为止的代码:
number *base6 = intToNumber(50, 6);
答案 0 :(得分:1)
您开始按照正确的思路进行思考,但是处理theNumbers
(您已评论)的分配只是第一步。当您分配theNumbers
时,将创建指针theNumbers->sNum
,但这是一个未初始化的指针,其中包含一个不确定地址作为其值。 (例如,它指向您没有任何能力使用的地方)。考虑一下您的结构(typedef
)
typedef struct {
int iNum; /* automatic storage types */
int base;
char *sNum; /* a pointer - hold address to something else */
} number; /* must point to valid memory addr */
为其中之一分配时,将分配2个整数值和1个具有自动存储类型并且可以分配值的字符指针。 iNum
和base
是整数值,可以为它们分配立即值,例如50
和6
,而sNum
是指针,只能分配一个有效内存地址存储其他内容的位置。
通常,要使用指针,您需要分配一个新的内存块,用该类型所需的内容填充该内存,然后将该新内存块的起始地址分配给指针({{1 }} 这里)。因此,现在您的指针将保存(例如指向)包含该对象类型可用值的有效内存块的地址。 (sNum
,这里是指向char的指针)
您的char*
函数仅使用intToNumber
和int nnum
作为参数,因此在分配int nbase
后,您只能初始化struct
和{{1 }},但没有大小或初始化theNumbers->iNum = nnum;
的内容(因此应将其设置为theNumbers->base = nbase;
)。
因此,您sNum
已经关闭,您需要做的就是在为其分配存储空间后返回指针NULL
(因为分配后它具有已分配的存储类型< / em>(在程序的整个生命周期内有效-或直到程序被释放),例如
intToNumber
现在如何处理intToNumber
?好的,这取决于您,但是例如,您可以创建一个单独的函数,该函数将分配的number *intToNumber (int nnum, int nbase) {
number *theNumbers;
theNumbers= malloc (sizeof *theNumbers); /* allocate */
if (theNumbers == NULL) { /* validate */
perror ("malloc-theNumbers");
return NULL;
}
theNumbers->iNum = nnum; /* initialize values */
theNumbers->base = nbase;
theNumbers->sNum = NULL;
return theNumbers; /* return pointer */
}
和一个字符串作为参数,分配sNum
个字节来容纳字符串(加上 nul-终止字符),将新博克的起始地址分配给struct
,然后将字符串复制到新的内存块中,例如
length + 1
(我怀疑您会用base6转换来填充它-但这留给您)
除了在完成处理后释放内存外,剩下的只是一个简短的示例,展示了如何将其完全整合在一起。您可以使用以下简单的方法来完成此操作:
sNum
使用/输出示例
如果将示例放在一起,将会得到:
/* allocate/set sNum member of n to s */
char *setsNum (number *n, const char *s)
{
if (!n) { /* validate n not NULL, return NULL on failure */
fputs ("error: struct parameter 'n' NULL.\n", stderr);
return NULL;
}
size_t len = strlen (s); /* get length */
n->sNum = malloc (len + 1); /* allocate storage (+1 byte) */
if (!n->sNum) { /* validate allocation */
perror ("malloc-sNum");
return NULL;
}
memcpy (n->sNum, s, len + 1); /* copy s to new block of memory */
return n->sNum; /* return pointer (convenience) */
}
内存使用/错误检查
在您编写的任何动态分配内存的代码中,对于任何分配的内存块,您都有2个职责:(1)始终保留指向起始地址的指针因此,(2)当不再需要它时可以释放。
当务之急是使用一个内存错误检查程序来确保您不会尝试访问内存或在已分配的块的边界之外/之外进行写入,不要试图以未初始化的值读取或基于条件跳转,最后,以确认您释放了已分配的所有内存。
对于Linux,int main (void) {
number *mynum = intToNumber (50, 6); /* declare/initialize mynum */
if (!mynum) /* validate succeeded */
return 1;
/* allocate/validate mynum->sNum, copy string */
if (!setsNum (mynum, "created with intToNumber (50, 6)")) {
free (mynum);
return 1;
}
/* output values held in mynum */
printf ("succeeded:\n iNum: %d\n base: %d\n str : %s\n",
mynum->iNum, mynum->base, mynum->sNum);
free (mynum->sNum); /* free allocated string */
free (mynum); /* free struct */
}
是正常选择。每个平台都有类似的内存检查器。它们都很容易使用,只需通过它运行程序即可。
$ ./bin/struct_alloc_member
succeeded:
iNum: 50
base: 6
str : created with intToNumber (50, 6)
始终确认已释放已分配的所有内存,并且没有内存错误。
使用的完整示例是:
valgrind
答案 1 :(得分:0)
假设实际问题恰好是标题中提出的内容
如何将结构从函数返回到结构指针?
答案是,尽管函数可以返回结构,但不能将其返回给指针。在任何情况下都不能将结构分配给任何指针类型的对象。您可以有一个指向结构的指针,也可以有一个包含指针的结构,但是没有一个结构本身就是指针。
另一方面,如果问题是关于如何返回结构指针,则答案将是“通过使用return
语句”,与返回任何其他类型的值的方式相同。为了使它有用,您返回的指针应该是有效的,但这是一个单独的问题。
答案 2 :(得分:0)
为什么不传递指向函数结构的指针,以使签名看起来像void intToNumber(number *n)
?然后您将使实现看起来像
int main ()
{
number Numbers = {.sNum = malloc (25) };
// Do stuff here...
intToNumber(&Numbers);
// Do some more stuff...
}
由于您指向堆栈上的变量Numbers
,因此可以在函数intToNumber
中操作这些变量,并使它们在main
函数的其余部分中可用(或在无论您决定调用它的范围是什么。