结构成员的功能指针分配导致类型铸造不匹配并最终分割故障
我编写了以下程序,以帮助我学习功能指针及其在结构中的用途:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
typedef struct S_t S_t;
struct S_t {
float *s_ptr;
uint32_t ns;
};
typedef struct p_t p_t;
struct p_t {
int32_t pID;
float pVal;
};
typedef struct pr_t pr_t;
struct pr_t {
S_t *S;
int (*TrimS)(S_t *TS, int sSize);
p_t *TP;
};
int ChopS(S_t *TS, int size);
float fvals[] = {0.8000000119209290, 0.2399999946355820, -0.3740000128746033,
0.2489999979734421, 0.9049999713897705, 0.3770000040531158,
-0.6959999799728394, -0.8870000243186951, -0.9739999771118164,
0.1410000026226044, 0.4040000140666962, 0.7779999971389771};
int arrLen = sizeof(fvals) / sizeof(fvals[0]);
float svals[20];
int ChopS(S_t *TS, int size)
{
int i, c;
for(i = 0; i < TS->ns; i++)
{
if (i >= size)
TS->s_ptr[i] = 0.0;
}
c = 0;
for(i = 0; i < TS->ns; i++)
{
if(TS->s_ptr[i] == 0.0)
c++;
}
if (c == size)
return 0;
else
return -1;
}
int main()
{
int i, n;
p_t p1 = {.pID = 1234, .pVal = 0.35};
p_t *p2 = NULL;
S_t tS1;
S_t *tS2 = NULL;
tS2 = malloc(sizeof(S_t));
pr_t SP1;
pr_t *SP2 = NULL;
SP2 = malloc(sizeof(pr_t));
p2 = (p_t *) malloc(sizeof(p_t));
p2->pID = 1111;
p2->pVal = 1.198;
printf("Generating new values from original inputs as float array : \n");
for(i = 0; i < n; i++)
{
svals[i] = 1 + fvals[i];
printf("%f, ", svals[i]);
}
printf("\n");
tS1.s_ptr = fvals;
tS1.ns = arrLen;
tS2->s_ptr = svals;
tS2->ns = arrLen;
SP1.S = &tS1;
SP1.TP = &p1;
SP1.TrimS = ChopS(&tS1, 4);
printf("Original inputs from PR1 (Trim=%d) as %d inputs : \n",
SP1.TrimS, SP1.S->ns);
for(i = 0; i < n; i++)
{
printf("%f, ", SP1.S->s_ptr[i]);
}
printf("\n");
SP2->S = tS2;
SP2->TP = p2;
SP2->TrimS = ChopS(&tS2, 8);
printf("Modified inputs from PR2 (Trim=%d) as %d inputs : \n",
SP2->TrimS, SP2->S->ns);
for(i = 0; i < n; i++)
{
printf("%f, ", SP2->S->s_ptr[i]);
}
printf("\n");
return 0;
}
它在编译时会给我以下警告:当
user@PCLT:~/Test$ gcc -std=c99 -Wall -o executetest exp.c
exp.c: In function ‘main’:
exp.c:95:15: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
SP1.TrimS = ChopS(&tS1, 4);
^
exp.c:96:45: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int (*)(S_t *, int) {aka int (*)(struct S_t *, int)}’ [-Wformat=]
printf("Original inputs from PR1 (Trim=%d) as %d inputs : \n",
~^
*(SP1.TrimS), SP1.S->ns);
~
exp.c:106:24: warning: passing argument 1 of ‘ChopS’ from incompatible pointer type [-Wincompatible-pointer-types]
SP2->TrimS = ChopS(&tS2, 8);
^
exp.c:39:5: note: expected ‘S_t * {aka struct S_t *}’ but argument is of type ‘S_t ** {aka struct S_t **}’
int ChopS(S_t *TS, int size)
^~~~~
exp.c:106:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
SP2->TrimS = ChopS(&tS2, 8);
^
exp.c:107:45: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int (*)(S_t *, int) {aka int (*)(struct S_t *, int)}’ [-Wformat=]
printf("Modified inputs from PR2 (Trim=%d) as %d inputs : \n",
~^
*(SP2->TrimS), SP2->S->ns);
~
我运行可执行文件时,我会得到以下信息:
user@PCLT:~/Test$ ./executetest
Generating new values from original inputs as float array :
1.800000, 1.240000, 0.626000, 1.249000, 1.905000, 1.377000, 0.304000, 0.113000, 0.026000, 1.141000, 1.404000, 1.778000,
Original inputs from PR1 (Trim=-1) as 12 inputs :
0.800000, 0.240000, -0.374000, 0.249000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
Segmentation fault (core dumped)
当我使用非 - 时,我得到了所需的结果。指针pr_t
变量SP1,但没有得到我使用指针pr_t
变量SP2时所需的结果。当我尽力而为时,我找不到问题。有人可以帮我指出我在这里做错了什么吗?
更新:
我修改了上述代码(在下面的评论中给出了 @pm100和@dmedine的建议),通过替换上述代码中的第95行中的第95行,
SP1.TrimS = ChopS;
SP1.TrimS(&tS1, 4);
并使用:106行,
SP2->TrimS = ChopS;
SP2->TrimS(tS2, 8);
并且运行良好。但是现在,问题是在第96和107行中以表格打印(TRIM = 94135985899402)
,而我期待沿行(TRIM = 0)
(此处,此处,我试图确保输入数组“ Trim”状态设置为0,这意味着操作是成功的)。这里可能有什么错?
I wrote the following program to help me learn function pointers and their use within structures:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
typedef struct S_t S_t;
struct S_t {
float *s_ptr;
uint32_t ns;
};
typedef struct p_t p_t;
struct p_t {
int32_t pID;
float pVal;
};
typedef struct pr_t pr_t;
struct pr_t {
S_t *S;
int (*TrimS)(S_t *TS, int sSize);
p_t *TP;
};
int ChopS(S_t *TS, int size);
float fvals[] = {0.8000000119209290, 0.2399999946355820, -0.3740000128746033,
0.2489999979734421, 0.9049999713897705, 0.3770000040531158,
-0.6959999799728394, -0.8870000243186951, -0.9739999771118164,
0.1410000026226044, 0.4040000140666962, 0.7779999971389771};
int arrLen = sizeof(fvals) / sizeof(fvals[0]);
float svals[20];
int ChopS(S_t *TS, int size)
{
int i, c;
for(i = 0; i < TS->ns; i++)
{
if (i >= size)
TS->s_ptr[i] = 0.0;
}
c = 0;
for(i = 0; i < TS->ns; i++)
{
if(TS->s_ptr[i] == 0.0)
c++;
}
if (c == size)
return 0;
else
return -1;
}
int main()
{
int i, n;
p_t p1 = {.pID = 1234, .pVal = 0.35};
p_t *p2 = NULL;
S_t tS1;
S_t *tS2 = NULL;
tS2 = malloc(sizeof(S_t));
pr_t SP1;
pr_t *SP2 = NULL;
SP2 = malloc(sizeof(pr_t));
p2 = (p_t *) malloc(sizeof(p_t));
p2->pID = 1111;
p2->pVal = 1.198;
printf("Generating new values from original inputs as float array : \n");
for(i = 0; i < n; i++)
{
svals[i] = 1 + fvals[i];
printf("%f, ", svals[i]);
}
printf("\n");
tS1.s_ptr = fvals;
tS1.ns = arrLen;
tS2->s_ptr = svals;
tS2->ns = arrLen;
SP1.S = &tS1;
SP1.TP = &p1;
SP1.TrimS = ChopS(&tS1, 4);
printf("Original inputs from PR1 (Trim=%d) as %d inputs : \n",
SP1.TrimS, SP1.S->ns);
for(i = 0; i < n; i++)
{
printf("%f, ", SP1.S->s_ptr[i]);
}
printf("\n");
SP2->S = tS2;
SP2->TP = p2;
SP2->TrimS = ChopS(&tS2, 8);
printf("Modified inputs from PR2 (Trim=%d) as %d inputs : \n",
SP2->TrimS, SP2->S->ns);
for(i = 0; i < n; i++)
{
printf("%f, ", SP2->S->s_ptr[i]);
}
printf("\n");
return 0;
}
It gives me the following warnings when I compile:
user@PCLT:~/Test$ gcc -std=c99 -Wall -o executetest exp.c
exp.c: In function ‘main’:
exp.c:95:15: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
SP1.TrimS = ChopS(&tS1, 4);
^
exp.c:96:45: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int (*)(S_t *, int) {aka int (*)(struct S_t *, int)}’ [-Wformat=]
printf("Original inputs from PR1 (Trim=%d) as %d inputs : \n",
~^
*(SP1.TrimS), SP1.S->ns);
~
exp.c:106:24: warning: passing argument 1 of ‘ChopS’ from incompatible pointer type [-Wincompatible-pointer-types]
SP2->TrimS = ChopS(&tS2, 8);
^
exp.c:39:5: note: expected ‘S_t * {aka struct S_t *}’ but argument is of type ‘S_t ** {aka struct S_t **}’
int ChopS(S_t *TS, int size)
^~~~~
exp.c:106:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
SP2->TrimS = ChopS(&tS2, 8);
^
exp.c:107:45: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int (*)(S_t *, int) {aka int (*)(struct S_t *, int)}’ [-Wformat=]
printf("Modified inputs from PR2 (Trim=%d) as %d inputs : \n",
~^
*(SP2->TrimS), SP2->S->ns);
~
And when I run the executable, I get the following:
user@PCLT:~/Test$ ./executetest
Generating new values from original inputs as float array :
1.800000, 1.240000, 0.626000, 1.249000, 1.905000, 1.377000, 0.304000, 0.113000, 0.026000, 1.141000, 1.404000, 1.778000,
Original inputs from PR1 (Trim=-1) as 12 inputs :
0.800000, 0.240000, -0.374000, 0.249000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
Segmentation fault (core dumped)
I got the desired result when I used the non-pointer pr_t
variable SP1 but didn't get the result I needed when I used the pointer pr_t
variable SP2. I am unable to find what went wrong as I tried to the best of my abilities. Can someone help me point out what I'm doing wrong here?
UPDATE:
I modified the above code (on suggestions given by @pm100 and @dmedine in the comments below) by replacing line 95 in the above code with:
SP1.TrimS = ChopS;
SP1.TrimS(&tS1, 4);
and line 106 with:
SP2->TrimS = ChopS;
SP2->TrimS(tS2, 8);
and it runs fine. But now, the problem is with lines 96 and 107 which prints in the form (Trim=94135985899402)
while I was expecting something along the lines (Trim=0)
(here, I am trying to make sure that the input array "trim" status is set to 0, meaning the operation was a success). What could be possibly wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论