取消引用双指针并使用索引运算符

时间:2012-06-22 13:05:17

标签: c string pointers

我将一个char **类型的双指针传递给一个函数。在该函数内部,我需要取消引用指针,然后通过字符数组进行索引。

不幸的是,当我尝试将大写字母分配回数组时,我正在获得核心转储。

我需要帮助来解决这个问题。 (这不是家庭作业,只是个人项目。)

void buffer(char **ppline);

int main()
{
  char *line="The redcoats are coming!";

  buffer(&line); 
  printf("\nline = %s\n",line);

  return(0);
}


void buffer (char **ppline)
{

 int i=0;
 char a;

  for (i=0; i < strlen(*ppline); i++)
  {
    a = toupper( (*ppline)[i] );   /* THIS LINE CAUSES THE CORE DUMP  */
    ((*ppline)[i]) = a;
  }

  return;
}

2 个答案:

答案 0 :(得分:2)

""中的字符串文字是常量。你不能像你一样修改它,因为这是未定义的行为。试试这个,它分配存储并将字符串文字复制到其中:

void buffer(char **ppline);

int main()
{
  char line[] = "The redcoats are coming!";

  buffer(&line); 
  printf("\nline = %s\n",line);

  return(0);
}


void buffer (char **ppline)
{

 int i=0;
 char a;

  for (i=0; i < strlen(*ppline); i++)
  {
    a = toupper( (*ppline)[i] );   /* THIS LINE CAUSES THE CORE DUMP  */
    ((*ppline)[i]) = a;
  }

  return;
}

答案 1 :(得分:1)

堆栈,堆,数据段(和BSS)和文本分段是进程内存的四个段。定义的所有局部变量都将在堆栈中。使用malloc和calloc以动态方式分配的内存将在堆中。所有全局变量和静态变量都将在数据段中。文本段将包含程序的汇编代码和一些常量。

在这4个部分中,文本段是READ ONLY段,而其他三个段都是READ和WRITE。

char []a="The redcoats are coming!"; - 这个statemnt将在堆栈中为25个字节分配内存(因为本地变量),它将保留所有24个字符加上NULL字符(\ 0)。

char *p="The redcoats are coming!"; - 这个语句将在堆栈中为4个字节(如果它是32位机器)分配内存(因为这也是一个局部变量)并且它将保存常量字符串的指针,其值为“红衣即将到来!“常量字符串的这个字节将在文本段中。这是一个恒定值。指针变量p只指向该字符串。

现在a[0](索引可以是0到24)表示,它将访问堆栈中该字符串的第一个字符。所以我们也可以在这个位置写作。 a[0] = 'x'允许此操作,因为我们在堆栈中具有READ WRITE访问权限。

但是p[0] = 'x'会导致崩溃,因为我们只有文本分段的READ访问权限。如果我们对文本段进行任何写操作,就会发生分段错误。

但是你可以改变变量p的值,因为它的局部变量在堆栈中。如下所示

char *p = "string";
printf("%s", p);
p = "start";
printf("%s", p);

这是允许的。这里我们将存储在指针变量p中的地址更改为字符串start的地址(同样start也是文本段中的只读数据)。如果要修改* p中的值,请选择动态分配的内存。

char *p = NULL;
p = malloc(sizeof(char)*7);
strcpy(p, "string");

现在允许p[0] = 'x'操作,因为现在我们正在写堆。