我正在尝试将动态分配的char数组初始化为称为term的结构中的不同类型,该结构包含多项式(系数,var,指数)的一部分。该函数是to_string函数,该函数以结构形式的字符串“ cx ^ e”或“ c”(如果该项的指数为0)返回结构项。
我相信我的整体思维过程对于创建字符串是正确的,但是我不知道我是否正确初始化了char *ptr
。
以下是相关代码:
to_string函数
char *term_to_string(const term_t *term)
{
char *ptr;
if (term->exponent == 0)
{
ptr = (char *) malloc(sizeof(term->coefficient));
memset(ptr, 'x', sizeof(term->coefficient));
*ptr = term->coefficient;
}
else if (term->coefficient == 1)
{
ptr = (char *) malloc(sizeof (term->var) + sizeof (term->exponent) + sizeof (char));
*ptr = term->var;
*(ptr + 1) = '^';
*(ptr + 2) = term->exponent;
}
else
{
ptr = (char *) malloc(sizeof(term->coefficient) +
sizeof(term->var) +
sizeof(term->exponent) +
sizeof(char));
*ptr = term->coefficient;
*(ptr + 1) = term->var;
*(ptr + 2) = '^';
*(ptr + 3) = term->exponent;
}
return ptr;
}
结构“项”
typedef struct term
{
int exponent, coefficient;
char var;
} term_t;
测试to_string
term_t testterm1 = {1, 'x', 0};
term_t testterm2 = {2, 'x', 1};
term_t testterm3 = {3, 'x', 2};
printf("Testing term.c/h:\n");
printf("testterm1: %s\n", term_to_string(&testterm1));
printf("testterm2: %s\n", term_to_string(&testterm2));
printf("testterm3: %s\n", term_to_string(&testterm3));
我一直收到分段错误错误,并且我知道它与尝试初始化NULL指针有关。但是,我对此感到困惑:
1)我应该将指针分配给什么大小? (我现在在{if1语句的第一块中使用sizeof(term->coefficient)
)
2)是否正确初始化了指针? (我在if语句的第一段中使用了memset
,但我真的认为我根本没有使用它)
预期结果应该是
x
2x
3x^2
任何帮助将不胜感激!!!
答案 0 :(得分:2)
您有四个问题:
term_to_string
返回的字符串没有被代码为0的字符终止,因此每个写入结果的 printf 都以未定义的行为退出分配的数组
您期望插入整数值的外部表示的方式是错误的,例如,将*ptr = term->coefficient
的一个字符设置为term->coefficient
强制转换(截断)为一个字符字符
计算分配的字符串大小的方法是错误的, int 的外部表示形式的大小不是 sizeof
给出的您对结构的初始化是错误的,第二个值('x')显然是char,但是您使用它初始化 coefficient 时,需要注意字段的顺序。
如果{3, 'x', 2};
必须产生3x^2
,这意味着 struct 的第一个字段必须是 coefficient (而不是 exponent < / em>),第二个必须是 var (而不是 coefficient ),而第三个必须是指数(而不是 var < / em>)。或者不更改 struct 的定义,您必须修改初始化顺序以使其具有term_t testterm3 = {2, 3, 'x'};
。
{1, 'x', 0}
也不能产生“ x”,它必须产生“ 1”或“ 0”
在不更改 struct 的定义和添加特殊情况下,您没有管理提案的情况可以是:
#include <stdio.h>
#include <malloc.h>
typedef struct term
{
int exponent, coefficient;
char var;
} term_t;
int snprintf(char *str, size_t size, const char *format, ...);
char *term_to_string(const term_t *term)
{
char *ptr;
if ((term->exponent == 0) || (term->coefficient == 0))
{
ptr = malloc(snprintf(NULL, 0, "%d", term->coefficient) + 1); /* +1 for char \0 */
sprintf(ptr, "%d", term->coefficient);
}
else if (term->coefficient == 1)
{
if (term->exponent == 1)
{
ptr = malloc(2);
ptr[0] = term->var;
ptr[1] = 0;
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d", term->exponent) + 3); /* +3 for var and ^ and char \0 */
sprintf(ptr, "%c^%d", term->var, term->exponent);
}
}
else if (term->coefficient == -1)
{
if (term->exponent == 1)
{
ptr = malloc(3);
ptr[0] = '-';
ptr[1] = term->var;
ptr[2] = 0;
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d", term->exponent) + 4); /* +4 for - and var and ^ and char \0 */
sprintf(ptr, "-%c^%d", term->var, term->exponent);
}
}
else if (term->exponent == 1)
{
ptr = malloc(snprintf(NULL, 0, "%d", term->coefficient) + 2); /* +2 for var and char \0 */
sprintf(ptr, "%d%c", term->coefficient, term->var);
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d%d", term->exponent, term->coefficient) + 3); /* +3 for var and ^ and char \0 */
sprintf(ptr, "%d%c^%d", term->coefficient, term->var, term->exponent);
}
return ptr;
}
int main()
{
term_t test[] = {
{0, 1, 'x'},
{1, 0, 'x'},
{1, 1, 'x'},
{1, -1, 'x'},
{1, 2, 'x'},
{2, 1, 'x'},
{2, -1, 'x'},
{2, 3, 'x'}
};
for (int i = 0; i != sizeof(test)/sizeof(term_t); ++i) {
char * s = term_to_string(&test[i]);
printf("test {exp=%d, coef=%d, var='%c'} : %s\n",
test[i].exponent, test[i].coefficient, test[i].var, s);
free(s);
}
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra e.c
pi@raspberrypi:/tmp $ ./a.out
test {exp=0, coef=1, var='x'} : 1
test {exp=1, coef=0, var='x'} : 0
test {exp=1, coef=1, var='x'} : x
test {exp=1, coef=-1, var='x'} : -x
test {exp=1, coef=2, var='x'} : 2x
test {exp=2, coef=1, var='x'} : x^2
test {exp=2, coef=-1, var='x'} : -x^2
test {exp=2, coef=3, var='x'} : 3x^2
pi@raspberrypi:/tmp $
在 valgrind 下执行:
pi@raspberrypi:/tmp $ valgrind ./a.out
==4285== Memcheck, a memory error detector
==4285== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4285== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4285== Command: ./a.out
==4285==
test {exp=0, coef=1, var='x'} : 1
test {exp=1, coef=0, var='x'} : 0
test {exp=1, coef=1, var='x'} : x
test {exp=1, coef=-1, var='x'} : -x
test {exp=1, coef=2, var='x'} : 2x
test {exp=2, coef=1, var='x'} : x^2
test {exp=2, coef=-1, var='x'} : -x^2
test {exp=2, coef=3, var='x'} : 3x^2
==4285==
==4285== HEAP SUMMARY:
==4285== in use at exit: 0 bytes in 0 blocks
==4285== total heap usage: 9 allocs, 9 frees, 1,050 bytes allocated
==4285==
==4285== All heap blocks were freed -- no leaks are possible
==4285==
==4285== For counts of detected and suppressed errors, rerun with: -v
==4285== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $