C语言 从 C 函数返回字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25798977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning string from C function
提问by MrWolf
I haven't used C in over 3 years, I'm pretty rusty on a lot of things.
我已经 3 年多没有使用 C 了,我在很多事情上都生疏了。
I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.hfor this.
我知道这可能看起来很愚蠢,但目前我无法从函数返回字符串。请假设:我不能string.h用于此。
Here is my code:
这是我的代码:
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = 'void getStr(char *wordd, int length) {
...
}
int main(void) {
char wordd[10 + 1];
getStr(wordd, sizeof(wordd) - 1);
...
}
';
return word;
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
I can capture the string (with my getStrfunction) but I cannot get it to display correctly (I get garbage).
我可以捕获字符串(使用我的getStr函数),但我无法正确显示它(我得到了垃圾)。
Help is appreciated.
帮助表示赞赏。
回答by michaelmeyer
Either allocate the string on the stack on the caller side and pass it to your function:
在调用方的堆栈上分配字符串并将其传递给您的函数:
char *getStr(void) {
static char wordd[10 + 1];
...
return wordd;
}
Or make the string static in getStr:
或将字符串设为静态getStr:
char *getStr(int length) {
char *wordd = malloc(length + 1);
...
return wordd;
}
Or allocate the string on the heap:
或者在堆上分配字符串:
char word[length];
char *rtnPtr = word;
...
return rtnPtr;
回答by nneonneo
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '#include <stdio.h>
char *c_hello() {
char *mystr = "Hello World!\n";
return mystr;
// return "this string"; // alterative
}
';
return strdup(&word[0]);
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
This is not good. You are returning a pointer to an automatic (scoped) variable, which will be destroyed when the function returns. The pointer will be left pointing at a destroyed variable, which will almost certainly produce "strange" results (undefined behaviour).
这是不好的。您正在返回一个指向自动(作用域)变量的指针,该变量将在函数返回时被销毁。指针将指向一个被破坏的变量,这几乎肯定会产生“奇怪”的结果(未定义的行为)。
You should be allocating the string with malloc(e.g. char *rtnPtr = malloc(length)), then freeing it later in main.
您应该使用malloc(eg char *rtnPtr = malloc(length))分配字符串,然后free稍后在main.
回答by Brian Campbell
You are allocating your string on the stack, and then returning a pointer to it. When your function returns, any stack allocations become invalid; the pointer now points to a region on the stack that is likely to be overwritten the next time a function is called.
您正在堆栈上分配字符串,然后返回指向它的指针。当您的函数返回时,任何堆栈分配都将无效;指针现在指向堆栈上的一个区域,该区域在下次调用函数时可能会被覆盖。
In order to do what you're trying to do, you need to do one of the following:
为了做您想做的事情,您需要执行以下操作之一:
- Allocate memory on the heap using
mallocor similar, then return that pointer. The caller will then need to callfreewhen it is done with the memory. - Allocate the string on the stack in the calling function (the one that will be using the string), and pass a pointer in to the function to put the string into. During the entire call to the calling function, data on its stack is valid; its only once you return that stack allocated space becomes used by something else.
- 使用
malloc或类似方法在堆上分配内存,然后返回该指针。调用者将需要在free完成内存后调用。 - 在调用函数(将使用字符串的函数)中的堆栈上分配字符串,并将指针传递给函数以将字符串放入。在调用函数的整个调用过程中,其堆栈上的数据都是有效的;只有当您返回堆栈分配的空间时,它才会被其他东西使用。
回答by Arpit
Your pointer is pointing to local variable of the function. So as soon as you return from the function, memory gets deallocated. You have to assign memory on heap in order to use it in other functions.
您的指针指向函数的局部变量。因此,一旦您从函数返回,内存就会被释放。您必须在堆上分配内存才能在其他功能中使用它。
Instead
char *rtnPtr = word;
反而
char *rtnPtr = word;
do this
char *rtnPtr = malloc(length);
做这个
char *rtnPtr = malloc(length);
So that it is available in the main function. After it is used free the memory.
这样就可以在主函数中使用了。使用后释放内存。
回答by John3136
wordis on the stack and goes out of scope as soon as getStr()returns. You are invoking undefined behavior.
word位于堆栈上并在getStr()返回后立即超出范围。您正在调用未定义的行为。
回答by Colin Weinshenker
回答by John 9631
I came across this thread while working on my understanding of Cython. My extension to the original question might be of use to others working at the C / Cython interface. So this is the extension of the original question: how do I return a string from a C function, making it available to Cython & thus to Python?
我在研究 Cython 时遇到了这个线程。我对原始问题的扩展可能对在 C/Cython 接口上工作的其他人有用。所以这是原始问题的扩展:如何从 C 函数返回一个字符串,使其可用于 Cython,从而可用于 Python?
For those not familiar with it, Cython allows you to statically type Python code that you need to speed up. So the process is, enjoy writing Python :), find its a bit slow somewhere, profile it, calve off a function or two and cythonize them. Wow. Close to C speed (it compiles to C) Fixed. Yay. The other use is importing C functions or libraries into Python as done here.
对于那些不熟悉它的人,Cython 允许您静态键入需要加速的 Python 代码。所以这个过程是,享受编写 Python :),发现它在某个地方有点慢,对其进行分析,分解一两个函数并对其进行 cythonize。哇。接近 C 的速度(它编译为 C)已修复。好极了。另一种用途是将 C 函数或库导入 Python 中,如此处完成。
This will print a string and return the same or another string to Python. There are 3 files, the c file c_hello.c, the cython file sayhello.pyx, and the cython setup file sayhello.pyx. When they are compiled using python setup.py build_ext --inplacethey generate a shared library file that can be imported into python or ipython and the function sayhello.hello run.
这将打印一个字符串并将相同或另一个字符串返回给 Python。有 3 个文件,c 文件 c_hello.c、cython 文件 sayhello.pyx 和 cython 安装文件 sayhello.pyx。当它们被编译时,它们会python setup.py build_ext --inplace生成一个共享库文件,该文件可以导入到 python 或 ipython 中,并运行函数 sayhello.hello。
c_hello.c
c_hello.c
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
sayhello.pyx
说你好.pyx
##代码##setup.py
设置文件
##代码##
