将内存分配给作为函数内部参数的指针
Allocating memory to a pointer giving as argument inside a function
我想编写一个可以将一个 C 字符串的内容复制到另一个 C 字符串的函数。
#include <stdio.h>
#include <string.h>
void copy(char*,char*);
int main(){
char* string = "hello";
char* destination;
copy(destination,string);
printf("Source: %s\nDestination: %s",string,destination);
system("pause");
return 0;
}
void copy(char* dest, char* src){
dest = malloc(strlen(src)*sizeof(char)); //Crashes
while (*src){
*dest++ = *src++;
}
}
在函数内部分配内存导致程序崩溃,而在函数调用起作用之前分配内存:
char* destination = malloc(strlen(string)*sizeof(char)); //works
问题是 copy
获取地址 - destination
的当前值和 source
的值。
然后用malloc
的结果覆盖destination
的当前值。
然后进行复制,malloc
ed 内存丢失。
return 复制 destination
的值,而不是传入它。
或使用char **
和*.
char * copy( char* src){
char * dest = malloc( (1+strlen(src))*sizeof(char)); //Crashes
char * toReturn = dest;
while (*src){
*dest++ = *src++;
}
return toReturn;
}
或
void copy( char ** dest, char* src){
/* overwrite pointer value with the result of malloc */
char * toCopy;
(*dest) = malloc((1+strlen(src))*sizeof(char)); //Crashes
toCopy = *dest;
while (*src){
*toCopy++ = *src++;
}
}
在您的 main()
函数中,您声明了一个类型为 char *
的变量 destination
而没有对其进行初始化。然后将 destination
作为参数传递给 copy()
函数。了解传递给 copy()
的数据很重要。在这种情况下,由于 destination
尚未初始化,我们不知道传递给 copy()
的内容。当您在函数调用之前 malloc()
时,这很好,因为在那种情况下,destination
已被初始化。特别是,它的值是由 malloc()
.
返回的堆中的某个地址
正如其他人指出的那样,您还应该小心分配比 src 字符串长度多 1 个字节,以便允许 space 作为空终止符。
已通过多种不同方式解释的主要问题与如何将 dest
传递给 copy()
有关。当您将指针传递给函数时,例如:
void copy(char* dest, char* src) {
函数接收一个副本的指针,它将指向相同的地址,但将有自己的不同地址.所以当你传递 char *dest
时,copy()
函数接收到 dest
指针的 copy。当您在 copy()
中分配 dest
时,调用者 main()
不知道 dest
在 copy()
中的地址是什么,也无法访问内存return由 dest = malloc(strlen(src)*sizeof(char));
在 copy()
编辑。
每当你在一个函数中分配内存时,如果你没有returning新分配的内存块的地址,你必须通过address of 指向函数的指针(不是指针的副本)。这样,当您调用 malloc
时,您将 malloc
的 return(新内存块的起始地址)指定为指针 处的值与 main()
中相同的地址 。
如果您什么都不记得了,请记住这条规则:如果您要为传递给函数的指针分配内存,则必须 (1) return 调用方的新地址;或 (2) 将指针的地址传递给函数进行分配。
这是另一个采用类似思路但采用几种不同方法的示例:
#include <stdio.h>
#include <stdlib.h>
void copy (char **dest, char *src);
int main (int argc, char **argv) {
char *str = argc > 1 ? argv[1] :
"A quick brown fox jumps over the lazy dog.";
char *dest = NULL;
copy (&dest, str);
printf ("\n str : %s\n dest : %s\n\n", str, dest);
free (dest); /* free allocated memory */
return 0;
}
void copy (char **dest, char *src)
{
if (!src) { /* validate src string */
fprintf (stderr, "%s() error: invalid string 'src'.\n",
__func__);
return;
}
size_t len = 0;
char *p = src;
for (;*p; p++, len++) {} /* strlen */
/* allocate and validate -- every time */
if (!(*dest = malloc (len * sizeof **dest + 1))) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n",
__func__);
exit (EXIT_FAILURE);
}
p = *dest; /* copy src to dest */
for (; *src; src++) *p++ = *src;
*p = 0; /* null-terminate */
}
输出
$ ./bin/copystr
str : A quick brown fox jumps over the lazy dog.
dest : A quick brown fox jumps over the lazy dog.
注意: 如果您不使用 gcc
然后将 __func__
更改为函数名称。
我想编写一个可以将一个 C 字符串的内容复制到另一个 C 字符串的函数。
#include <stdio.h>
#include <string.h>
void copy(char*,char*);
int main(){
char* string = "hello";
char* destination;
copy(destination,string);
printf("Source: %s\nDestination: %s",string,destination);
system("pause");
return 0;
}
void copy(char* dest, char* src){
dest = malloc(strlen(src)*sizeof(char)); //Crashes
while (*src){
*dest++ = *src++;
}
}
在函数内部分配内存导致程序崩溃,而在函数调用起作用之前分配内存:
char* destination = malloc(strlen(string)*sizeof(char)); //works
问题是 copy
获取地址 - destination
的当前值和 source
的值。
然后用malloc
的结果覆盖destination
的当前值。
然后进行复制,malloc
ed 内存丢失。
return 复制 destination
的值,而不是传入它。
或使用char **
和*.
char * copy( char* src){
char * dest = malloc( (1+strlen(src))*sizeof(char)); //Crashes
char * toReturn = dest;
while (*src){
*dest++ = *src++;
}
return toReturn;
}
或
void copy( char ** dest, char* src){
/* overwrite pointer value with the result of malloc */
char * toCopy;
(*dest) = malloc((1+strlen(src))*sizeof(char)); //Crashes
toCopy = *dest;
while (*src){
*toCopy++ = *src++;
}
}
在您的 main()
函数中,您声明了一个类型为 char *
的变量 destination
而没有对其进行初始化。然后将 destination
作为参数传递给 copy()
函数。了解传递给 copy()
的数据很重要。在这种情况下,由于 destination
尚未初始化,我们不知道传递给 copy()
的内容。当您在函数调用之前 malloc()
时,这很好,因为在那种情况下,destination
已被初始化。特别是,它的值是由 malloc()
.
正如其他人指出的那样,您还应该小心分配比 src 字符串长度多 1 个字节,以便允许 space 作为空终止符。
已通过多种不同方式解释的主要问题与如何将 dest
传递给 copy()
有关。当您将指针传递给函数时,例如:
void copy(char* dest, char* src) {
函数接收一个副本的指针,它将指向相同的地址,但将有自己的不同地址.所以当你传递 char *dest
时,copy()
函数接收到 dest
指针的 copy。当您在 copy()
中分配 dest
时,调用者 main()
不知道 dest
在 copy()
中的地址是什么,也无法访问内存return由 dest = malloc(strlen(src)*sizeof(char));
在 copy()
编辑。
每当你在一个函数中分配内存时,如果你没有returning新分配的内存块的地址,你必须通过address of 指向函数的指针(不是指针的副本)。这样,当您调用 malloc
时,您将 malloc
的 return(新内存块的起始地址)指定为指针 处的值与 main()
中相同的地址 。
如果您什么都不记得了,请记住这条规则:如果您要为传递给函数的指针分配内存,则必须 (1) return 调用方的新地址;或 (2) 将指针的地址传递给函数进行分配。
这是另一个采用类似思路但采用几种不同方法的示例:
#include <stdio.h>
#include <stdlib.h>
void copy (char **dest, char *src);
int main (int argc, char **argv) {
char *str = argc > 1 ? argv[1] :
"A quick brown fox jumps over the lazy dog.";
char *dest = NULL;
copy (&dest, str);
printf ("\n str : %s\n dest : %s\n\n", str, dest);
free (dest); /* free allocated memory */
return 0;
}
void copy (char **dest, char *src)
{
if (!src) { /* validate src string */
fprintf (stderr, "%s() error: invalid string 'src'.\n",
__func__);
return;
}
size_t len = 0;
char *p = src;
for (;*p; p++, len++) {} /* strlen */
/* allocate and validate -- every time */
if (!(*dest = malloc (len * sizeof **dest + 1))) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n",
__func__);
exit (EXIT_FAILURE);
}
p = *dest; /* copy src to dest */
for (; *src; src++) *p++ = *src;
*p = 0; /* null-terminate */
}
输出
$ ./bin/copystr
str : A quick brown fox jumps over the lazy dog.
dest : A quick brown fox jumps over the lazy dog.
注意: 如果您不使用 gcc
然后将 __func__
更改为函数名称。