更改指针指向的字符串

时间:2009-11-03 13:10:07

标签: c pointers

c中的许多函数将指针指向常量字符串/字符作为参数,例如void foo(const char *ptr)。但是我希望更改它所指向的字符串(ptr)。如何在c

中执行此操作

7 个答案:

答案 0 :(得分:2)

你可以抛弃const

void evil_function(const char *ptr)
{
  char *modifiable = (char *) ptr;

  *modifiable = 'f';
}

请注意,这很危险,请考虑传递给函数的数据确实无法更改的情况。例如,evil_function("bar");可能会崩溃,因为字符串文字通常放在只读内存中。

答案 1 :(得分:1)

不要这样做会导致代码无法预测。基本上const char *指向的字符串可能存储在程序数据的只读部分中,如果你尝试在那里写一些东西,就会发生坏事。请记住,foo可以被称为foo("Test"),在这里你没有为自己的“Test”分配内存,你只需要一个指向包含字符串的内存的指针。该内存可能是只读的。

答案 2 :(得分:1)

您可以将其复制到另一块内存中,并在那里进行修改。

如果你把它转换为非const,然后修改,很可能你只是段错误。

答案 3 :(得分:1)

void foo(const char *x);
char data[4] = "Hi!";
int sum = 0;
for (int k=0; k<strlen(data); k++) {
    foo(data);           /* foo first */
    sum += data[k];
}
printf("%d\n", sum);

由于foo()不会更改其参数,因此编译器可以将此代码更改为

void foo(const char *x);
char data[4] = "Hi!";
int sum = 0;
for (int k=0; k<strlen(data); k++) {
    sum += data[k];      /* sum first */
    foo(data);
}
printf("%d\n", sum);

但是,如果foo()更改data数组中的值,则结果将根据编译器选择编码循环的顺序而有所不同!

简而言之:不要欺骗你的编译器

如何欺骗编译器

远离const

void foo(const char *readonly) {
    char *writable = (char *)readonly;
    /* now lie to the compiler all you like */
}

答案 4 :(得分:0)

用符号“const char * ptr”我们告诉编译器 ptr包含的内容不应该更改。

只是,我们无法改变它!

答案 5 :(得分:0)

const的全部原因是为了表示底层内容不被这个函数修改,所以不要改变它,因为这很可能会破坏一些依赖于const的代码。除此之外,您始终可以使用const_cast<char*>或直接转换指针

来抛弃常量

答案 6 :(得分:-1)

如果你这样做:

void dont_do_this_at_home(const char *ptr)
{
  char **steve-o_ptr = (char **) &ptr;
  char *bam_margera = "viva la bam";

  *steve-o_ptr = bam_margera;
}

然后,尽管是一个const指针,你发送到函数中的指针也会被改变,到目前为止,其他建议只允许你改变字符串的内容,而不是指向字符串的指针。

我同意其他人你不应该,永远,“un-const”你得到的任何参数,因为被调用者可能真的依赖于没有副作用这些参数的功能。

还有这种方法可以摆脱警告/错误

typedef struct {
    union {
        const void* the_const;
        void* the_no_const;
    } unconsting;
}unconst_t;

/* Here be dragons */
void* unconst_pointer(const void* ptr) {
    unconst_t unconst.unconsting.the_const = ptr;
    return unconst.unconsting.the_no_const;
}

如你所见,实际上很有可能也很受欢迎,但你必须知道自己在做什么,否则可能会出现神秘的错误。