C 编程 - 将未声明的字符串传递给函数(内存分配)
C Programming - Passing an Undeclared String to a Function (Memory Allocation)
我有一个关于将 undeclared String
传递给 Function
的问题。
下面的代码编译和工作正常(因为字符串被正确打印)。我试图了解代码在内存分配方面如何工作的细节 (编译器是否从 "String" 生成临时变量并将其实际传递给函数?).
通常我会声明一个 char
数组来保存字符串,然后将其传递给函数 - 这在内存分配方面很有意义。
如果按照下面的程序直接传递字符串(例如,一个长 运行 程序将大量字符串传递给日志 -每个字符串传递是否创建某种新的字符串变量,其内存永远不会被释放等)。
代码 - Visual Studio 2013 年编译
#include <stdio.h>
//Function Declaration
int MyFunction(char *SomeString);
int main(void)
{
MyFunction("MyString");
return 0;
}
//Function Code
int MyFunction(char *SomeString) {
printf("Passed String: %s \n", SomeString);
return 0;
}
编译器创建一个字符串文字,当您调用 MyFunction("MyString")
时,指向该字符串文字的指针将传递给该函数。只要您的程序运行,"Mystring"
字符串就会存在。
这个:
MyFunction("MyString");
或多或少等同于
static char *mystring = "MyString";
MyFunction(mystring);
I have a question relating to passing an undeclared String
to a Function
.
不,您没有在此处传递 未声明的 字符串。在你的情况下,
MyFunction("MyString");
"MyString"
被称为 字符串文字 并且可以被认为是一个未命名的变量。通常,这驻留在不可修改的内存中。
内存分配由编译器在编译期间自行处理,因此您无需为内存分配和释放部分操心。
您的程序中没有内存泄漏。字符串文字的类型 N 个字符长为 const char[N+1]
(+1
用于 NUL 终止符)。实际上,您的程序有一个 const char[9]
类型的隐藏全局对象,其中包含字符 M
y
S
t
r
i
n
g
NUL
。您使用文字 "MyString"
.
引用此对象
当传递给 MyFunction
时,会创建一个 char *
类型的临时自动对象,它指向该数组中的第一个字符(这是所有数组都会发生的标准转换)。通话结束时,该临时文件将再次被销毁。数组本身的内存不是动态分配的,因此不会泄漏。
函数参数被认为是相应函数参数的初始值设定项。你可以想象这个函数调用
MyFunction("MyString");
以下方式
int MyFunction( /*char *SomeString*/) {
char *SomeString = "MyString";
printf("Passed String: %s \n", SomeString);
return 0;
}
函数调用中使用的字符串文字具有字符数组类型char[9]
,并具有静态存储持续时间。也就是说,当编译器编译程序时,它将程序中使用的每个字符串文字作为字符数组放置在静态内存中。
在函数调用中,对应于字符串文字的字符数组被隐式转换为指向其第一个字符的指针。也就是说,编译器创建一个 char *
类型的临时对象,其值等于字符串文字(静态数组)的第一个字符的地址,并将其作为函数的参数压入堆栈。
所以更准确地说是函数调用
MyFunction("MyString");
可以想像
char *tmp = "MyString";
MyFunction( tmp );
//...
int MyFunction( /*char *SomeString*/) {
char *SomeString = tmp;
printf("Passed String: %s \n", SomeString);
return 0;
}
我有一个关于将 undeclared String
传递给 Function
的问题。
下面的代码编译和工作正常(因为字符串被正确打印)。我试图了解代码在内存分配方面如何工作的细节 (编译器是否从 "String" 生成临时变量并将其实际传递给函数?).
通常我会声明一个 char
数组来保存字符串,然后将其传递给函数 - 这在内存分配方面很有意义。
如果按照下面的程序直接传递字符串(例如,一个长 运行 程序将大量字符串传递给日志 -每个字符串传递是否创建某种新的字符串变量,其内存永远不会被释放等)。
代码 - Visual Studio 2013 年编译
#include <stdio.h>
//Function Declaration
int MyFunction(char *SomeString);
int main(void)
{
MyFunction("MyString");
return 0;
}
//Function Code
int MyFunction(char *SomeString) {
printf("Passed String: %s \n", SomeString);
return 0;
}
编译器创建一个字符串文字,当您调用 MyFunction("MyString")
时,指向该字符串文字的指针将传递给该函数。只要您的程序运行,"Mystring"
字符串就会存在。
这个:
MyFunction("MyString");
或多或少等同于
static char *mystring = "MyString";
MyFunction(mystring);
I have a question relating to passing an
undeclared String
to aFunction
.
不,您没有在此处传递 未声明的 字符串。在你的情况下,
MyFunction("MyString");
"MyString"
被称为 字符串文字 并且可以被认为是一个未命名的变量。通常,这驻留在不可修改的内存中。
内存分配由编译器在编译期间自行处理,因此您无需为内存分配和释放部分操心。
您的程序中没有内存泄漏。字符串文字的类型 N 个字符长为 const char[N+1]
(+1
用于 NUL 终止符)。实际上,您的程序有一个 const char[9]
类型的隐藏全局对象,其中包含字符 M
y
S
t
r
i
n
g
NUL
。您使用文字 "MyString"
.
当传递给 MyFunction
时,会创建一个 char *
类型的临时自动对象,它指向该数组中的第一个字符(这是所有数组都会发生的标准转换)。通话结束时,该临时文件将再次被销毁。数组本身的内存不是动态分配的,因此不会泄漏。
函数参数被认为是相应函数参数的初始值设定项。你可以想象这个函数调用
MyFunction("MyString");
以下方式
int MyFunction( /*char *SomeString*/) {
char *SomeString = "MyString";
printf("Passed String: %s \n", SomeString);
return 0;
}
函数调用中使用的字符串文字具有字符数组类型char[9]
,并具有静态存储持续时间。也就是说,当编译器编译程序时,它将程序中使用的每个字符串文字作为字符数组放置在静态内存中。
在函数调用中,对应于字符串文字的字符数组被隐式转换为指向其第一个字符的指针。也就是说,编译器创建一个 char *
类型的临时对象,其值等于字符串文字(静态数组)的第一个字符的地址,并将其作为函数的参数压入堆栈。
所以更准确地说是函数调用
MyFunction("MyString");
可以想像
char *tmp = "MyString";
MyFunction( tmp );
//...
int MyFunction( /*char *SomeString*/) {
char *SomeString = tmp;
printf("Passed String: %s \n", SomeString);
return 0;
}