结构成员的功能指针分配导致类型铸造不匹配并最终分割故障

发布于 2025-02-10 21:05:15 字数 4791 浏览 1 评论 0原文

我编写了以下程序,以帮助我学习功能指针及其在结构中的用途:

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文