【问题标题】:Char Pointer allocation within a function - Segmentaion fault函数内的字符指针分配 - 分段错误
【发布时间】:2017-01-17 12:26:59
【问题描述】:

我正在尝试将内存分配给函数内的 char 指针。但是我在for cycle at i=1 的函数内部遇到了分段错误。对于i=0它分配内存。我正在努力解决这个问题。也许其他“眼睛”可以看出问题所在。

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

void AllocateDeallocate(int, int, int, char***);

int main(void)
{
    char** header1;
    char** header2;
    AllocateDeallocate(1,3,40,&header1);

    return 0;
}

void AllocateDeallocate(int iopt, int nStr, int StrLen, char*** Str)
{
    int i;
    switch (iopt)
    {
    case 1:
        if (NULL == Str)
        {           
            exit(EXIT_FAILURE);
        }
        if(*Str == NULL)
        {
            *Str = (char**)malloc(sizeof(char*)*nStr);          
            if (*Str== NULL)
            {
                puts("Memory allocation failed.");
                exit(EXIT_FAILURE);
            }       
        }
        for(i = 0 ; i< nStr;i++)
        {   
            printf("String %d allocation\n",i); 
            *Str[i] = (char*)malloc(sizeof(char)*(StrLen+1));
            if (*Str[i] == NULL)
            {
                puts("Memory allocation failed.");
                exit(EXIT_FAILURE);
            }
        }
        break;
    case 2:
        for( i = 0; i<nStr; i++)
        {
            free(*Str[i]);
        }
        free(*Str);
        break;
    default:
        printf("Wrong Option");
    }
}   

【问题讨论】:

  • 所有*Str[i] 都应该是(*Str)[i]
  • 与您的问题无关,但sizeof(char) 根据定义始终为 1。并且您不应该从malloc() 和朋友那里投射返回值。
  • 您的 AllocateDeallocate 函数会查看 *Str 以将其与 NULL 进行比较——但调用者从未给 header1 一个值,所以您正在查看垃圾。
  • 旁注:三个间接级别char*** Str 似乎过分了。您可能需要重新考虑您的设计。
  • 对我来说,让一个函数同时进行分配和释放的设计似乎有缺陷。这将使代码更难阅读和维护,尤其是使用magic numbers

标签: c pointers


【解决方案1】:

当您调用函数AllocateDeallocate 时,变量header1 未初始化。这意味着函数 *Str 内部有一个 indeterminate 值(并且看起来是随机的)。

当您随后使用*Str(例如*Str == NULL)时会导致问题(因为该值很可能等于NULL)。

简单的解决方案?初始化main函数中的变量:

char** header1 = NULL;
char** header2 = NULL;

一旦您解决了上述问题,您就会遇到其他问题。就像你做*Str[i]一样。由于operator precedence 规则,它等于*(Str[i]),这不是你想要的。您需要显式使用括号来拥有(*Str)[i]


上述两个问题都会导致未定义的行为,并可能导致崩溃。

【讨论】:

  • 已解决。我忘记了。
猜你喜欢
  • 2011-07-23
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多