简体   繁体   English

传递双指针的分段错误

[英]Segmentation fault to the pass double pointer

The following code causes segmentation fault to the pass double pointer to strcpy 以下代码导致分段错误传递给strcpy的双指针

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

void funcion(char ***ptr)
{
    *ptr = malloc(2 * (sizeof(char*)));
    (*ptr)[0] = malloc(5 * sizeof(char));
    (*ptr)[1] = malloc(5 * sizeof(char));
    strcpy(*ptr[0],"AAAA");
    strcpy(*ptr[1], "BBBB");
}
int main()
{
    char **p;
    funcion(&p);
    printf("%s %s\n", p[0], p[1]);
    return 0;
}

What is the difference between *ptr[1] and (*ptr)[1]? * ptr [1]和(* ptr)[1]有什么区别?

One of the best ways to cement in your mind the way to handle dereferencing, is too sit down and write the same allocation routine several different ways. 牢记处理取消引用的最佳方法之一就是坐下来,用几种不同的方法编写相同的分配例程。 All allowable, but as the sound advice in the comments points out, some of the ways make more sense than others. 都可以,但是正如评论中的合理建议所指出的那样,某些方式比其他方式更有意义。 Take your first example, you can pass the address of a pointer to pointer to char , but it may not be the best way to go. 以您的第一个示例为例,您可以将指针地址传递给char的指针 ,但这可能不是最好的方法。 For example, you can write your funcion [sic] in the following manner, 例如,你可以写你的funcion [原文]通过以下方式,

/* called passing address of p */
void function (char ***ptr)
{
    *ptr = malloc (2 * sizeof *ptr);

    (*ptr)[0] = malloc (5 * sizeof(char));
    (*ptr)[1] = malloc (5 * sizeof(char));

    strcpy ((*ptr)[0], "AAAA");
    strcpy ((*ptr)[1], "BBBB");
}

There is no need to pass anything to your function if all of your allocation and data is contained in the function. 如果所有分配和数据都包含在函数中,则无需将任何内容传递给函数。 You simply need to assign the return from the function. 您只需要分配函数的收益 For example: 例如:

/* p simply assigning the address of ptr */
char **function2 (void)
{
    char **ptr = malloc (2 * sizeof *ptr);

    ptr[0] = malloc (5 * sizeof(char));
    ptr[1] = malloc (5 * sizeof(char));

    strcpy (ptr[0], "AAAA");
    strcpy (ptr[1], "BBBB");

    return ptr;
}

Since the function allocates memory for the pointers and also allocates storage for the hardcoded "AAAA" and "BBBB" values, all you need back from the function is the address for ptr which you can assign to p . 由于该函数为指针分配内存,并且还为硬编码的"AAAA""BBBB"值分配存储,因此,您需要从函数中返回的是ptr的地址,可以分配p You simply need to match the function type for the required return. 您只需要匹配所需返回的函数type You can then access all values from the calling function through p . 然后,您可以通过p从调用函数访问所有值。

You can also look at tools available to simplify what it is you are trying to accomplish. 您还可以查看可用的工具来简化您要完成的工作。 For example strdup can both allocate and copy a string. 例如, strdup可以分配和复制字符串。 You could further simplify function2 above as: 您可以将上面的function2进一步简化为:

/* a simplified version of funciton2 */
char **function3 (void)
{
    char **ptr = malloc (2 * sizeof *ptr);

    ptr[0] = strdup ("AAAA");
    ptr[1] = strdup ("BBBB");

    return ptr;
}

Finally, whenever you allocate data, you need to preserve a pointer to the starting address for each block, so you can free the information when it is no longer in use. 最后,每当分配数据时,都需要保留一个指向每个块的起始地址的指针,以便可以在不再使用该信息时free它们。 For your case above, a simple function (which isn't necessarily needed as a function) could be: 对于上述情况,一个简单的函数(不一定是一个函数)可能是:

/* always free all allocated memory */
void free_p (char **p)
{
    free (p[0]);
    free (p[1]);
    free (p);
}

Putting that altogether in a bit of test code, you could use all 3 to accomplish the same task: 将其全部放入一点测试代码中,就可以使用全部3个来完成相同的任务:

int main (void)
{
    char **p = NULL;

    function (&p);
    printf ("%s %s\n", p[0], p[1]);
    free_p (p);

    p = function2();
    printf ("%s %s\n", p[0], p[1]);
    free_p (p);

    p = function3();
    printf ("%s %s\n", p[0], p[1]);
    free_p (p);

    return 0;
}

Example Use/Output 使用/输出示例

$ ./bin/ptrp
AAAA BBBB
AAAA BBBB
AAAA BBBB

Don't forget to validate your memory use with a memory error checker (such as valgrind for Linux). 不要忘了使用内存错误检查器(例如valgrind for Linux)来验证您的内存使用情况。 They are simple to use and available for all platforms. 它们易于使用,可用于所有平台。 Example: 例:

$ valgrind ./bin/ptrp
==17888== Memcheck, a memory error detector
==17888== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==17888== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==17888== Command: ./bin/ptrp
==17888==
AAAA BBBB
AAAA BBBB
AAAA BBBB
==17888==
==17888== HEAP SUMMARY:
==17888==     in use at exit: 0 bytes in 0 blocks
==17888==   total heap usage: 9 allocs, 9 frees, 78 bytes allocated
==17888==
==17888== All heap blocks were freed -- no leaks are possible
==17888==
==17888== For counts of detected and suppressed errors, rerun with: -v
==17888== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

Always confirm All heap blocks were freed -- no leaks are possible and equally important ERROR SUMMARY: 0 errors from 0 contexts . 始终确认所有堆块都已释放-不可能发生泄漏,并且同等重要。 错误摘要:0个上下文中的0个错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM