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

  • 本文关键字:函数 调用 指针 数组 空间 分配 c
  • 更新时间 :
  • 英文 :


我有这段代码func我正在获取指向指针数组的指针。此函数的目的是将字符串写入两个分配的空间以进行chars。在主中分配。我在这一行得到段错误

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("%sn",arr[0]);
printf("%sn", arr[1]);
return 0;
}

我已经使用

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

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

func(&arr);

传递指针变量数组地址的要点arr这样我可以看到main(...)中字符串空间的更改,以及FUNC中所做的更改

但是这条线引起了麻烦

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

赛段错误

谁能告诉我我做错了什么,这个答案也与指针数组有关。 https://stackoverflow.com/a/69551741/4808760

我期待的输出是

hell
hi

瓦尔格林德垃圾场

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,则必须在末尾手动添加。请注意,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("%sn",arr[0]);
printf("%sn", arr[1]);
free(arr);
return 0;
}

一种方法是:

#include <stdio.h>
#include <stdlib.h>
void func(char **c)
{
c[0] = malloc(strlen("hel") + 1);
c[1] = malloc(strlen("hi") + 1);
strcpy(c[0], "hel");
strcpy(c[1], "hi");
}
int main()
{
char *arr[2];
func(arr);
printf("%sn",arr[0]);
printf("%sn", arr[1]);
return 0;
}

在这里,arr是一个包含两个指向char的指针的数组。当我们将数组传递给函数时,它会衰减到指向第一个元素的指针。因此,func()接受指向char的指针。c[0]c[1]将保存由malloc()返回的地址,以保留c内的偏移量。然后,strcpy()只是将传递的字符串复制到分配的空间。当此函数返回时,main()发现数据已经放置在arr[0]arr[1]中。

或者,您也可以在func()中调用strdup()。另外,不要忘记打电话给free()

在此语句中

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

arr是指向2字符数组的指针。然而,您正在为其分配210字符数组的内存。它应该是

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

&arr的类型是char (**)[10],所以func()函数参数的类型应该是char (**)[10]

void func(char (**c)[10])
^^^^

func()函数中,您应该分别访问第一个和第二个数组,如(*c)[0](*c)[1]

我期待的输出是

地狱

您正在计算字符数,要复制,要memcpy()作为sizeof("hel").您想要输出hell还是hel?我相信(或假设),您希望将字符串文字"hello"的第一个3个字符复制到(*c)[0]

请注意,sizeof("hel")将给出输出4,因为它也包含空终止符字符。因此,memcpy()将从字符串文字"hello"中复制4个字符。如果要从字符串"hello"复制第一个3字符,则应将计数传递为sizeof("hel") - 1

此外,在使用memcpy()复制字符后,您应该附加空终止符字符memcpy()因为不会自动附加终止空字符。你可以做这样的事情:

memcpy((*c)[0],"hello",sizeof("hel") - 1);
(*c)[0][sizeof("hel") - 1] = '';    // append null terminator character 

最后,遵循良好的编程实践,始终检查malloc()返回,并确保在完成后free()动态分配的内存。

把这些放在一起,你可以做到:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char (**c)[10]) {
memcpy((*c)[0], "hello", sizeof("hel") - 1);
(*c)[0][sizeof("hel") - 1] = '';
memcpy((*c)[1], "hi", sizeof("hi") - 1);
(*c)[1][sizeof("hi") - 1] = '';
}
int main(void) {
char (*arr)[10] = malloc(sizeof(char[2][10]));
if (arr == NULL) {
fprintf (stderr, "Failed to allocate memoryn");
exit(EXIT_FAILURE);
}
func(&arr);
printf("%sn", arr[0]);
printf("%sn", arr[1]);
free(arr);
return 0;
}

输出:

# ./a.out
hel
hi

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

由于在调用函数之前main()函数中将内存分配给arr指针func()因此无需传递arr的地址来反映从函数返回后main()函数中字符串空间func()更改。只需将arr传递给func()函数即可。当你传递arr时,这意味着你正在将指向分配内存的指针传递给func()函数,因此,func()中写入该内存的任何内容都将反映在main()中。您还需要更改func()参数的类型,使其与char (*)[10]arr类型相同,并分别访问第一个和第二个数组,如c[0]c[1]。你可以做

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char (*c)[10]) {
memcpy(c[0], "hello", sizeof("hel") - 1);
c[0][sizeof("hel") - 1] = '';
memcpy(c[1], "hi", sizeof("hi") - 1);
c[1][sizeof("hi") - 1] = '';
}
int main(void) {
char (*arr)[10] = malloc(sizeof(char[2][10]));
if (arr == NULL) {
fprintf (stderr, "Failed to allocate memoryn");
exit(EXIT_FAILURE);
}
func(arr);
printf("%sn", arr[0]);
printf("%sn", arr[1]);
free(arr);
return 0;
}

谢谢我从巴邦得到的答案。

我还可以在 main 中分配空格,或者如果我需要在一行中创建空格,那么这将是char (*arr)[2]=malloc(sizeof(char[2][2])),但我没有得到如何在链接答案中的主函数或调用函数中传递和分配数据的答案。 只是告诉我如何分配它

void func(char **c)
{
memcpy(c[0],"hello",sizeof("hel"));
memcpy(c[1],"hi",sizeof("hi"));
//  memcpy(*c[2],"hell",sizeof("hell"));
//  c[0]="hello";
//c[1]="hi";
}
int main()
{
char *arr[2];
arr[0]=malloc(sizeof(char[2][10]));
arr[1]=malloc(sizeof(char[2][10]));
func(arr);
printf("%sn",arr[0]);
printf("%sn", arr[1]);
return 0;
}

相关内容

  • 没有找到相关文章

最新更新