如何将 char 数组作为对函数和 memcpy 的引用传递

发布于 2025-01-03 22:36:48 字数 751 浏览 0 评论 0原文

从早上起我就一直在努力解决这个问题。值 'pd' pm 在函数外部不会更改。有人能告诉我错误是什么吗?

void foo(u8 *pm, u8 *pd) 
{
    pm = "IWR ";
    memcpy(pd, pm, sizeof(pm));
    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

int main()
{
    u8 pm[5] = "0";
    u8 pd[5] = "IWO ";
    printf("pm = %s, pd = %s \n", pm, pd);  
    foo(pm, pd);
    printf("after pm = %s, pd = %s \n", pm, pd);
}

调用 foo 后我的最终输出是 pm = (null) 和 pd = "IWO "。我认为“pm”也会改变价值。

(这是 ideone 上的代码,但在这种情况下 pm 打印为 0,而不是 (null)。)

pm = 0, pd = IWO  
in foo pm = IWR , pd = IWR  
after pm = 0, pd = IWR  

I've been struggling to fix this since morning. The value 'pd' pm doesn't change outside the function. Could someone tell me what the mistake is?

void foo(u8 *pm, u8 *pd) 
{
    pm = "IWR ";
    memcpy(pd, pm, sizeof(pm));
    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

int main()
{
    u8 pm[5] = "0";
    u8 pd[5] = "IWO ";
    printf("pm = %s, pd = %s \n", pm, pd);  
    foo(pm, pd);
    printf("after pm = %s, pd = %s \n", pm, pd);
}

My final output after call to foo is pm = (null) and pd = "IWO ". I thought that 'pm' also would change value.

(Here is the code on ideone, but in that case pm prints as 0, not (null). Why is this? )

pm = 0, pd = IWO  
in foo pm = IWR , pd = IWR  
after pm = 0, pd = IWR  

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

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

发布评论

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

评论(3

治碍 2025-01-10 22:36:48
  1. 函数 foo() 中的 sizeof(pm) 是指针的大小。不是数组的大小,正如您所假设的那样。
  2. 我猜你的意思是 pm 在函数之外不会改变,因为给定你的程序,pd 肯定会改变。 pm 没有改变的原因是因为 C(以及您使用它的方式的 C++)是一种按值传递语言。 C 常见问题解答有一个关于您的问题的问题
  1. sizeof(pm) in your function foo() is the size of a pointer. Not the size of the array, as it looks like you're assuming.
  2. I guess you mean that pm doesn't change outside the function, since given your program, pd most certainly does. The reason pm doesn't change is because C (and C++ in the way you're using it) is a pass-by-value language. The C FAQ has a question about precisely your problem.
云裳 2025-01-10 22:36:48

您可以使用模板通过引用传递数组:

template<typename T, unsigned int Length1, unsigned int Length2>
void foo(T(&pm)[Length], T(&pd)[Length2]) {
    memcpy(pd, "IWR ", Length2 - 2); // - 2 for the NULL
    pd[Length2 - 1] = 0;

    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

并以与之前使用 foo 相同的方式使用它。请注意,这仅适用于数组,不适用于指针。

请注意,

pm = "IWR ";

在原始函数中不执行任何操作(仅修改本地指针变量),并且在此修改后的函数中不起作用(无法分配给数组)。如果您想这样做,您还必须使用memcpy。

如果您不想使用模板,那么您必须将每个数组的大小传递到函数中(或使用哨兵值,但不要这样做),因为当您将数组传递到函数时(不通过引用)它会衰减为指针,虽然 sizeof(array) 会给出数组中的字节数,但 sizeof(pointer) 只会给出字节数在一个不是你想要的指针中。

You can pass an array by reference with a template:

template<typename T, unsigned int Length1, unsigned int Length2>
void foo(T(&pm)[Length], T(&pd)[Length2]) {
    memcpy(pd, "IWR ", Length2 - 2); // - 2 for the NULL
    pd[Length2 - 1] = 0;

    printf("in foo pm = %s, pd = %s \n", pm, pd);
}

And use it the same way you were using foo before. Note that this will only work with arrays, not with pointers.

Note that

pm = "IWR ";

Doesn't do anything in your original function (just modifies the local pointer variable) and doesn't work in this modified one (can't assign to arrays). If you want to do that, you'll have to use memcpy as well.

If you don't want to use templates, then you'll have to pass the size of each array into the function (or use a sentinel value but don't) because when you pass an array into a function (without passing it by reference) it decays to a pointer, and while sizeof(array) will give you the number of bytes in an array, sizeof(pointer) just gives you the number of bytes in a pointer which is not what you want.

妞丶爷亲个 2025-01-10 22:36:48

您好,通过执行 pm = "IWR" 您已经更改了 pm 指向 const 引用的内容。即,您已经完全更改了指针 pm (函数内部)以指向不同的位置。

if you do this inside the function your code would work as expected. See why its failing below.


    pm[0] = 'I';
    pm[1] = 'W';
    pm[2] = 'R';

    before foo in main
    ----------
     print pm "0\000\000\000"
     print &pm ==  (u8 (*)[5]) 0x7fbffff7b0

    in foo as soon as we enter
    ------
     print pm = (u8 *) 0x7fbffff7b0 "0" (you are pointing to the same location as in main )
     print pm = (u8 **) 0x7fbffff788

    ----     pm = "IWR" ---
   print pm = 0x400adc "IWR" (now pm is pointing to location in memory where const IWR is stored )
   print &pm = (u8 **) 0x7fbffff788

   ---back to main ---
     print pm =  "0\000\000\000" ( we havent changed anything on location fff7bo so no affect )
     print &pm $8 = (u8 (*)[5]) 0x7fbffff7b0 

谷歌改变链表的头部,你应该能够找到正确的解释

cslibrary.stanford.edu/103/LinkedListBasics.pdf [看看改变头指针]

Hi by doing pm = "IWR" you have changed what pm have been pointing to a const reference. i.,e you have completely changed the pointer pm ( inside the function ) to point to a different location.

if you do this inside the function your code would work as expected. See why its failing below.


    pm[0] = 'I';
    pm[1] = 'W';
    pm[2] = 'R';

    before foo in main
    ----------
     print pm "0\000\000\000"
     print &pm ==  (u8 (*)[5]) 0x7fbffff7b0

    in foo as soon as we enter
    ------
     print pm = (u8 *) 0x7fbffff7b0 "0" (you are pointing to the same location as in main )
     print pm = (u8 **) 0x7fbffff788

    ----     pm = "IWR" ---
   print pm = 0x400adc "IWR" (now pm is pointing to location in memory where const IWR is stored )
   print &pm = (u8 **) 0x7fbffff788

   ---back to main ---
     print pm =  "0\000\000\000" ( we havent changed anything on location fff7bo so no affect )
     print &pm $8 = (u8 (*)[5]) 0x7fbffff7b0 

Google for changing the head of linked list and you should be able to find proper explanation

cslibrary.stanford.edu/103/LinkedListBasics.pdf [ take a look changing head pointer ]

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