Eu não uso C há mais de 3 anos, estou muito enferrujado em muitas coisas.
Eu sei que isso pode parecer estúpido, mas não posso retornar uma string de uma function no momento. Por favor, assuma que: Eu não posso usar string.h
para isso.
Aqui está o meu código:
#include char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; return word; } int main() { char wordd[10]; initscr(); *wordd = getStr(10); printw("The string is:\n"); printw("%s\n",*wordd); getch(); endwin(); return 0; }
Eu posso capturar a string (com minha function getStr
), mas não consigo mostrá-la corretamente (recebo lixo).
Ajuda é apreciada.
Aloque a string na pilha no lado do chamador e passe para a sua function:
void getStr(char *wordd, int length) { ... } int main(void) { char wordd[10 + 1]; getStr(wordd, sizeof(wordd) - 1); ... }
Ou torne a string estática em getStr
:
char *getStr(void) { static char wordd[10 + 1]; ... return wordd; }
Ou aloque a string no heap:
char *getStr(int length) { char *wordd = malloc(length + 1); ... return wordd; }
char word[length]; char *rtnPtr = word; ... return rtnPtr;
Isto não é bom. Você está retornando um ponteiro para uma variável automática (com escopo), que será destruída quando a function retornar. O ponteiro ficará apontando para uma variável destruída, o que quase certamente produzirá resultados “estranhos” (comportamento indefinido).
Você deve estar alocando a string com malloc
(por exemplo, char *rtnPtr = malloc(length)
), depois char *rtnPtr = malloc(length)
free
a mais tarde no main
.
Você está alocando sua seqüência na pilha e, em seguida, retornando um ponteiro para ele. Quando sua function retorna, qualquer alocação de pilha se torna inválida; o ponteiro agora aponta para uma região na pilha que provavelmente será sobrescrita na próxima vez que uma function for chamada.
Para fazer o que você está tentando fazer, você precisa seguir um destes procedimentos:
malloc
ou similar e, em seguida, retorne esse ponteiro. O chamador precisará, então, chamar free
quando for feito com a memory. Seu ponteiro está apontando para a variável local da function. Então, assim que você retornar da function, a memory será desalocada. Você tem que atribuir memory na pilha, a fim de usá-lo em outras funções.
Em vez disso, char *rtnPtr = word;
faça isso char *rtnPtr = malloc(length);
De modo que está disponível na function principal. Depois é usado para liberar a memory.
word
está na pilha e sai do escopo assim que getStr()
retorna. Você está invocando um comportamento indefinido.
Ainda mais fácil: retornar um ponteiro para uma string que foi malloc com strdup .
#include char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; 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; }
Eu me deparei com esta discussão enquanto trabalhava no meu entendimento sobre o Cython. Minha extensão para a pergunta original pode ser útil para outras pessoas que trabalham na interface do C / Cython. Portanto, esta é a extensão da pergunta original: como faço para retornar uma string de uma function C, tornando-a disponível para o Cython e, assim, para o Python?
Para aqueles que não estão familiarizados com ele, o Cython permite que você digite estaticamente o código Python que precisa acelerar. Portanto, o processo é, divirta-se escrevendo Python :), encontre um pouco lento em algum lugar, faça o perfil dele, pare uma function ou duas e cifreie-as. Uau. Perto da velocidade C (compila para C) Fixo. Yay. O outro uso é importar funções ou bibliotecas C para o Python, como feito aqui.
Isso imprimirá uma string e retornará a mesma ou outra string para o Python. Existem 3 arquivos, o arquivo c c_hello.c, o arquivo cython sayhello.pyx e o arquivo de instalação do cython sayhello.pyx. Quando eles são compilados usando python setup.py build_ext --inplace
eles geram um arquivo de biblioteca compartilhada que pode ser importado para python ou ipython e a function sayhello.hello é executada.
c_hello.c
#include char *c_hello() { char *mystr = "Hello World!\n"; return mystr; // return "this string"; // alterative }
sayhello.pyx
cdef extern from "c_hello.c": cdef char* c_hello() def hello(): return c_hello()
setup.py
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 )