简体   繁体   English

通过动态分配内存来更改字符指针中的字符

[英]changing a character in a character pointer by allocating memory dynamically

here i am dynamically allocating memory to p so that i can change a particular character of a string, but this code hangs in the middle 在这里,我正在为p动态分配内存,以便可以更改字符串的特定字符,但是此代码挂在中间

 int main()
 {
  char *p;
  p=malloc(10*sizeof(char));
  p="string";
  p[0]='d';
  printf("%s",p);
 }

i tried replacing p="string" at line no 5 with strcpy(p, "string") and the code worked perfectly.can anyone tell me the reason behind this. 我试图用strcpy(p, "string")替换p="string" 5行的p="string" ,并且代码运行完美。任何人都可以告诉我其背后的原因。

 int main()
 {
   char *p;
   p=malloc(10*sizeof(char));
   strcpy(p, "string");
   p[0]='d';
   printf("%s",p);
 }

A pointer can either own a resource (malloc) or point a resource already owned by another entity. 指针可以拥有资源(malloc),也可以指向另一个实体已经拥有的资源。 When you do p="string"; 当你做p="string"; , you are creating a const char * to which you assign the character pointer p , there by leaking the malloc'd memory in the previous line, in the latter, you're just replacing the contents inside the malloc'd memory; ,您正在创建一个const char * ,并为其分配了字符指针p ,在那里,通过泄漏前一行中的malloc内存,在后一行中,您只是替换了malloc的内存中的内容; former is a bug/issue, latter is not. 前者是错误/问题,后者不是。 It is to be noted that although it's bad practise to leak resources/memory, it isn't the reason behind the hang. 要注意的是,尽管泄漏资源/内存是不明智的做法,但这并不是挂起的原因。

The reason you get a hang is because the edit you make in your C code under the hood tries to edit you're program's read-only memory space ( const char * variables are created as immutable byte arrays in this segment of the program memory). 挂起的原因是因为您在后台的C代码中所做的编辑尝试编辑您程序的只读存储空间( const char *变量在程序存储器的这一段中创建为不可变字节数组) 。 when does c++ allocate/deallocate string literals explains further on this. C ++何时分配/取消分配字符串文字对此进行了进一步说明。

As for passing the required bytes to malloc , a good practise to avoid using type in the expression: 至于将所需的字节传递给malloc ,一个好的做法是避免在表达式中使用type:

const size_t count_required = 10;
char *p = malloc(sizeof(*p) * count_required);
// changing p's type to int* would also work without editing the malloc argument

when the type of p is changed to, say, float , int or any other type the expression will continue to work fine without any changes. 当p的类型更改为floatint或任何其他类型时,表达式将继续正常运行而无需进行任何更改。

The line 线

 p="string";

changes p to point to a read-only string literal, leaking the previously allocated memory in the process. 更改p使其指向只读字符串文字,从而在进程中泄漏先前分配的内存。 You can't write to a string literal so p[0]='d'; 您无法写入字符串文字,因此p[0]='d'; will likely cause a seg fault. 可能会导致段故障。

Your second version, uses 您的第二个版本,使用

strcpy(p, "string");

to copy a the contents of read-only string literal into the memory you previously allocated. 将只读字符串文字的内容复制到您先前分配的内存中。 You're still using the buffer you dynamically allocated here so are safe to change its contents in later code. 您仍在使用此处动态分配的缓冲区,因此可以在以后的代码中安全地更改其内容。

One other very minor point, sizeof(char) is guaranteed to be 1 so you can simplify your malloc call to 另一个非常小的要点,保证sizeof(char)为1,因此您可以简化对malloc调用

 p=malloc(10);

Strings are not values, in C. You cannot copy strings around using assignment ( = ), but you can assign pointers (pointers are "real" values). 在C语言中,字符串不是值。不能使用赋值( = )复制字符串,但是可以分配指针(指针是“真实”值)。

To copy a string into your newly allocated memory, you need: 要将字符串复制到新分配的内存中,您需要:

strcpy(p, "string");

The way you've written it, you are overwriting the pointer returned by malloc() with the address of a static string constant. 编写方式是用静态字符串常量的地址覆盖malloc()返回的指针。 This causes a memory leak ; 这会导致内存泄漏 avoiding them is one of the challenges that makes C such a rewarding language to program in. 避免使用它们是使C成为一种有价值的编程语言的挑战之一。

firstly, there is a memory leak in your first program. 首先,第一个程序中存在内存泄漏。 You malloc and then assign the pointer to another constant string. 您先分配malloc ,然后将指针分配给另一个常量字符串。

Secondly, in the first program, you're modifying a CONSTANT string. 其次,在第一个程序中,您正在修改CONSTANT字符串。 but the second "CORRECT" program, you're duplicating that constant string and copying it into the memory allocated. 但是在第二个“ CORRECT”程序中,您正在复制该常量字符串并将其复制到分配的内存中。 Which, you're free to change. 您可以自由更改。

char amessage[] = "now is the time"; /* an array */

char *pmessage = "now is the time"; /* a pointer */

" amessage is an array, just big enough to hold the sequence of characters and '\\0' that initializes it. Individual characters within the array may be changed but amessagewill always refer to the samestorage. On the other hand, pmessage is a pointer, initialized to point to a string constant; the pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to modify the string contents." amessage是一个数组,大小足以容纳字符序列和用于初始化它的'\\0' 。该数组中的各个字符可能会更改,但amessage将始终引用相同的存储。另一方面, pmessage是指针,初始化为指向字符串常量;可以随后将指针修改为指向其他位置,但是如果您尝试修改字符串内容,则结果不确定。”

courtsey K&R Courtsey K&R

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

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