c - 指向调用函数中分配的空间并写入被调用函数的指针数组

标签 c

我在 func 中有这段代码,我正在获取指向指针数组的指针。此函数的目的是将字符串写入两个为 chars 分配的空间。分配在主要。我在这一行遇到了 segFault

memcpy(*c[1],"hi",sizeof("hi"));

这是完整的代码

void func(char (**c)[])
{
  memcpy(*c[0],"hello",sizeof("hel"));
  memcpy(*c[1],"hi",sizeof("hi"));
}

int main()
{
  char (*arr)[2]=malloc(sizeof(char[2][10]));
  func(&arr);
  printf("%s\n",arr[0]);
  printf("%s\n", arr[1]);
  return 0;
}

我已经分配了指针数组使用

char (*arr)[2]=malloc(sizeof(char[2][10]));

现在传递我这样调用的两个分配的字符串空间的地址

func(&arr);

传递指针数组地址的要点 arr 所以我可以看到 main(...) 中字符串空间的变化,在函数

但是这条线造成了麻烦

memcpy(*c[1],"hi",sizeof("hi"));

段错误

任何人都可以告诉我我做错了什么这个答案也与指针数组有关。 https://stackoverflow.com/a/69551741/4808760

我期望的输出是

hell
hi

Valgrind 转储

valgrind --leak-check=full -s ./a.out 
==7397== Memcheck, a memory error detector
==7397== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7397== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==7397== Command: ./a.out
==7397== 
==7397== Invalid write of size 2
==7397==    at 0x4849F23: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7397==    by 0x1091F2: func (test.c:8)
==7397==    by 0x10922A: main (test.c:18)
==7397==  Address 0x54698dcdde89a700 is not stack'd, malloc'd or (recently) free'd
==7397== 
==7397== 
==7397== Process terminating with default action of signal 11 (SIGSEGV)
==7397==  General Protection Fault
==7397==    at 0x4849F23: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7397==    by 0x1091F2: func (test.c:8)
==7397==    by 0x10922A: main (test.c:18)
==7397== 
==7397== HEAP SUMMARY:
==7397==     in use at exit: 30 bytes in 1 blocks
==7397==   total heap usage: 1 allocs, 0 frees, 30 bytes allocated
==7397== 
==7397== LEAK SUMMARY:
==7397==    definitely lost: 0 bytes in 0 blocks
==7397==    indirectly lost: 0 bytes in 0 blocks
==7397==      possibly lost: 0 bytes in 0 blocks
==7397==    still reachable: 30 bytes in 1 blocks
==7397==         suppressed: 0 bytes in 0 blocks
==7397== Reachable blocks (those to which a pointer was found) are not shown.
==7397== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7397== 
==7397== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==7397== 
==7397== 1 errors in context 1 of 1:
==7397== Invalid write of size 2
==7397==    at 0x4849F23: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7397==    by 0x1091F2: func (test.c:8)
==7397==    by 0x10922A: main (test.c:18)
==7397==  Address 0x54698dcdde89a700 is not stack'd, malloc'd or (recently) free'd
==7397== 
==7397== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

最佳答案

要解决您的代码实际存在的问题:

  • 您没有包含相关标题。
  • char (*arr)[2] 是错误的。您希望它指向 char [2][10] 的第一项。这是一个包含 2 个项目的数组,其中每个项目是一个包含 10 个字符的数组。因此指针应该是 char (*arr)[10]
  • func(&arr); 没有意义,没有理由通过引用传递指针,除非您打算更改指针本身(例如在函数内部执行 malloc 时)。<
  • char (**c)[] 是废话。这是指向不完整数组类型的指针数组的指针。但是您不能将不完整的数组类型作为参数传递给函数。这应该是 char str[2][10],它作为参数“衰减”为等效的 char (*str)[10]
  • 不能在子字符串上使用 memcpy,因为它不附加 nul 终止符。如果你使用 memcpy,那么你必须在末尾手动添加一个 \0。请注意,malloc(与 calloc 不同)不会对分配的内存进行零初始化。
  • 您忘记调用 free()。是的,操作系统将释放内存,但您仍应显式调用 free(),因为这会增加在设计阶段早期暴露堆损坏/指针/内存泄漏错误的机会。

更正后的代码:

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

void func(char str[2][10])
{
  strcpy(str[0],"hello");
  strcpy(str[1],"hi");
}

int main (void)
{
  char (*arr)[10]=malloc(sizeof(char[2][10]));
  func(arr);
  printf("%s\n",arr[0]);
  printf("%s\n", arr[1]);
  free(arr);
  return 0;
}

关于c - 指向调用函数中分配的空间并写入被调用函数的指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69566206/

相关文章:

c - 在c程序中使用diskpart

c - 如果我有一个 void 指针,我如何将一个 int 放入其中?

c - 如果未定义则跳过函数调用

f77 未格式化二进制文件的内容

c - 如何使用c在linux终端上显示鼠标的行走过程?

c - 如何在 C 中使用来自 #define 的指针和定义

c - IPC 使用 fork() 和 pipe()

c - 我需要帮助,将 C 代码翻译成 Mips,任何事情都会受到赞赏

c - 在 OpenGL 中与黑暗背景上的明亮图形混合不好(没有吸引力)

c - 'struct structVarable' 类型的空指针内的成员访问