无法将主函数中的整数集复制到copy()函数中动态分配的内存

发布于 2025-02-06 16:58:49 字数 1475 浏览 2 评论 0原文

以下是程序:

#include <stdio.h>
#include<stdlib.h>

int *glob_var;
int* copy(void *a,int size)
{
    int *t=(int *)calloc(1,sizeof(int));
    int i;
    int *glob_var=(int *)calloc(size,sizeof(int));
    printf("glob_var=%p\n",glob_var);
    printf("a=%p\n",a);
    t=glob_var;
    for(i=0;i<size;i++)
    {
        *glob_var=*(int *)a;
         glob_var++;

         (int *)a++;
        // printf("a=%p\n",a);

    }
    glob_var=t;
     for(i=0;i<10;i++)
    {
       printf("%d\t",*glob_var);
       glob_var++;

    }
glob_var=t;
printf("\n%p\n",glob_var);
return t;
}
int main() {
    // Write C code here
    int a=0x123456,i;
    int *var=(int *)calloc(10,sizeof(int));
    int *temp;
    temp=var;
    for(i=0;i<10;i++)
    {
        *var=i;
        var++;

    }
    var=temp;
    for(i=0;i<10;i++)
    {
       printf("%d\n",*var);
        var++;


    }
    var=temp;
    printf("var=%p\n",var);

    glob_var=copy(var,10);
    printf("%p\n",glob_var);

    for(i=0;i<10;i++)
    {
       printf("%d\t",*glob_var);
       glob_var++;

    }
    return 0;
}

但是,我获得的输出是:

0       16777216        65536   256     1       33554432        131072  512     2       50331648

我期望:0 1 2 3 4 5 6 7 8 9

但是,在copy()函数中,如果我将(int *)a ++;替换为a =(int *)a+1;它在起作用。

我的问题是:当前程序有什么问题?

Below is the program:

#include <stdio.h>
#include<stdlib.h>

int *glob_var;
int* copy(void *a,int size)
{
    int *t=(int *)calloc(1,sizeof(int));
    int i;
    int *glob_var=(int *)calloc(size,sizeof(int));
    printf("glob_var=%p\n",glob_var);
    printf("a=%p\n",a);
    t=glob_var;
    for(i=0;i<size;i++)
    {
        *glob_var=*(int *)a;
         glob_var++;

         (int *)a++;
        // printf("a=%p\n",a);

    }
    glob_var=t;
     for(i=0;i<10;i++)
    {
       printf("%d\t",*glob_var);
       glob_var++;

    }
glob_var=t;
printf("\n%p\n",glob_var);
return t;
}
int main() {
    // Write C code here
    int a=0x123456,i;
    int *var=(int *)calloc(10,sizeof(int));
    int *temp;
    temp=var;
    for(i=0;i<10;i++)
    {
        *var=i;
        var++;

    }
    var=temp;
    for(i=0;i<10;i++)
    {
       printf("%d\n",*var);
        var++;


    }
    var=temp;
    printf("var=%p\n",var);

    glob_var=copy(var,10);
    printf("%p\n",glob_var);

    for(i=0;i<10;i++)
    {
       printf("%d\t",*glob_var);
       glob_var++;

    }
    return 0;
}

However, the output I got is :

0       16777216        65536   256     1       33554432        131072  512     2       50331648

I was expecting: 0 1 2 3 4 5 6 7 8 9.

But, in the copy() function, if I replace (int *)a++; with a=(int *)a+1; it is working.

My question is: What is wrong with the current program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人│生佛魔见 2025-02-13 16:58:49

在C 1 中不允许使用指针到磁体上的算术(void*),并且您的编译器应在以下行中警告您(至少) :

(int *)a++;

当我编译您的代码(在Visual Studio中使用Clang-Cl编译器)时,我确实会为该行获取两个警告:

警告:在void指针上算术是GNU扩展[-wpointer-arith]
警告:表达结果未使用[-wunused-value]

这些问题中的第一个解决了我的开场行中提到的问题(并在脚注中进行了讨论),但第二个应该引起警钟。这表明铸件无法按预期工作 - 它实际上应用于a ++操作的结果,因为演员表的优先级低于informent

但是,当您使用a =(int *)a + 1;时,所有人都按预期工作,因为a指针被施加到int * 执行算术(然后将分配的void*隐式施放)。

(您的代码中还有其他问题,例如您功能中的glob_var的重新删除,以及使用非void Pointers作为%p格式>格式specifier的参数在几个printf调用中 - 但是这些与您的报告并不相关。 >我是否会施放malloc的结果?)


1 一些C编译器(例如GCC)确实允许算术算术* pointers,但我不知道此类操作的“基本单位大小”是什么。一个人必须读取GCC手册才能确定这一点,但是仅通过1而不是sizeof(int),您的程序所需的size>,上班。实际上,如果该假设是正确的,并且sizeof(int)4在您的平台上,它将解释您的连续'真实'数据之间的三个“垃圾值”输出。

Arithmetic on a pointer-to-void (void*) is not allowed in C1 and your compiler should warn you about that (at the very least) in the following line:

(int *)a++;

When I compile your code (using the clang-cl compiler in Visual Studio), I do, indeed, get two warnings for that line:

warning : arithmetic on a pointer to void is a GNU extension [-Wpointer-arith]
warning : expression result unused [-Wunused-value]

The first of these addresses the issue mentioned in my opening line (and discussed in the footnote) but it is the second that should be ringing alarm bells. That shows that the cast isn't working as intended – it is actually applied to the result of the a++ operation, because the cast has lower precedence than the post-increment.

However, when you use a = (int *)a + 1;, then all is working as intended, because the a pointer is cast to an int* before the arithmetic is performed (and then implicitly cast back to a void* for the assignment).

(There are other issues in your code, like the re-declaration of glob_var in your function, and the use of non-void pointers as arguments for the %p format specifier in several printf calls – but these are not really related to your reported problem. Also, this is worth a read: Do I cast the result of malloc?)


1 Some C compilers, such as GCC, do allow arithmetic on void* pointers, but I do not know what the 'base unit size' is for such operations. One would have to read the GCC manual to determine that, but it may very well by just 1, rather than the sizeof(int) required for your program, as presented, to work. Indeed, if that assumption is correct, and sizeof(int) is 4 on your platform, it would explain the three "garbage values" between successive 'real' data in your output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文