我有这段代码,其中complexp
是指向struct
的指针,表示复数。第一个printf
命令工作正常,并打印complexp
个内容。但是,第二个printf
无法正常工作并打印0
两次(这是不正确的)。
这两行之间没有代码。
int main()
{
ComplexP complexp = (ComplexP) malloc(sizeof(ComplexP));
complexp = fromCharFunc(s);
printf("complexp: real: %f, imaginary: %f\n", complexp->real, complexp->imaginary);
printf("1complexp: real: %f, imaginary: %f\n", complexp->real, complexp->imaginary);
return 0;
}
typedef struct Complex {
double real;
double imaginary;
} Complex;
typedef struct Complex* ComplexP;
ComplexP fromCharFunc(char * s)
{
if(s == NULL)
{
return NULL;
}
char* sreal;
char* simaginary;
double real;
double imaginary;
char str [DEFAULT_SIZE];
strcpy(str, s);
sreal = strtok(str, REALL_PART_DELIMITER);
simaginary = strtok(NULL, IMAGINARY_PART_DELIMITER);
int len1 = strlen(sreal) + strlen(simaginary);
int len2 = strlen(s) - strlen(IMAGINARY_PART_DELIMITER);
int diff = len1 == len2 ? 0 : 1;
if(diff)
{
return NULL;
}
if(verifyIsNumber(sreal))
{
real = atof(sreal);
}
else
{
return NULL;
}
if(verifyIsNumber(simaginary))
{
imaginary = atof(simaginary);
}
else
{
return NULL;
}
Complex complex = {real, imaginary};
ComplexP complexp = &complex;
return complexp;
}
/**
* @brief determines whether a string represents a number
* @param char *s poiter to a string
* #retrun 0 if not a number, 1 if is a number
*/
int verifyIsNumber(char *s)
{
char c;
int i = 0;
while( *(s+i) != '\0')
{
c = *(s+i);
if ((c >= MIN_DIGIT && c <= MAX_DIGIT) || c == POINT || c == MINUS)
i++;
else
{
return 0;
}
}
return 1;
}
答案 0 :(得分:1)
我能够重现你的问题。问题来自以下几点:
ComplexP fromCharFunc(char * s)
{
/* ... */
Complex complex = {real, imaginary};
ComplexP complexp = &complex;
return complexp;
}
这里,complex
是一个堆栈变量,这意味着一旦函数返回它就会超出范围。第一次打印正确答案的事实是半巧合,可能是基于数据尚未被覆盖的事实。这是未定义的行为。如果您需要引用生存,请使用calloc()
或malloc()
分配您的内存,并且不要忘记稍后free()
。您可以在我的示例中看到calloc()
正在工作,尽管在简短示例中我省略了free()
调用。
我尝试了你的代码(在把它变成一个完整的工作示例之后,这会有所帮助!),它可以工作:
#include <stdio.h>
#include <stdlib.h>
typedef struct Complex {
double real;
double imaginary;
} Complex;
typedef struct Complex* ComplexP;
int main(int argc, char **argv) {
ComplexP complexp = calloc(sizeof(Complex), 1);
complexp->real = 42;
complexp->imaginary = 100.5;
printf("complexp: real: %f, imaginary: %f\n", complexp->real,
complexp->imaginary);
printf("complexp: real: %f, imaginary: %f\n", complexp->real,
complexp->imaginary);
return 0;
}
因此,代码中必须存在未显示的内容。我建议从一个较小的示例开始,像我一样,然后重新添加功能,直到找到问题为止。
complex
类型另外,如果你不知道,C99 already includes a standard definition for complex numbers。您可以查看<complex.h>
,看看它是否符合您的需求。
答案 1 :(得分:1)
您正在返回指向局部变量的指针。在范围的末尾删除该变量。您应该考虑返回Complex
变量而不是ComplexP
。
ComplexP fromCharFunc(char * s)
{
// ...
// This variable is deleted after the function ends
Complex complex = {real, imaginary};
// After deletion, this pointer points to invalid memory
ComplexP complexp = &complex;
return complexp;
}
您的第一个printf
调用有效,因为complex
中的值仍然恰好位于指针所指向的内存位置。这是未定义的行为。使用不同的编译器或不同的系统,可能会导致两个printf
命令失败,或者两者都成功。
如果您想返回ComplexP
,则应使用malloc
保留记忆。
ComplexP fromCharFunc(char * s)
{
// ...
// Create a temporary variable
Complex complex = {real, imaginary};
// Reserve memory for your return variable
ComplexP complexp = malloc(sizeof(Complex));
// Copy your temporary variable to the reserved memory location
*complexp = complex;
return complexp;
}
答案 2 :(得分:0)
您可以使用gdb调试程序。在到达第二个printf语句之前,必须释放指针。只有使用gdb才能轻松解决此问题。
要跟踪问题,必须在编译时在程序中启用调试符号。您可以通过提供-g标志来完成此操作。