简体   繁体   English

C将char数组传递给函数,用另一个char数组计算并复制

[英]C passing char array to function, compute with another char array and copy

I would like to do something like that : 我想做那样的事情:

#include <stdio.h>

char * myfunction(char * in);
void myfunction2(char * in, const char ** content);

int main(){
    char * name="aName";
    char * result = myfunction(name);
    return 0;
}

char * myfunction(char * in) {
    const char *test = NULL;
    myfunction2(in, &test);
    return test; // I would like to return the value of test
}

void myfunction2(char * in, const char ** content) {
    char input[1024];
    //do some stuff to fill input
    *content = input;
}

But I'm not able to do it, some weird char are printed instead sometimes... 但是我无法做到,有时会打印一些奇怪的字符......

Thank you for your reply, I understand it well now, but I'm stuck on another side of my problem. 谢谢你的回复,我现在理解得很清楚,但我仍然困在我问题的另一面。 I didn't write precisely my use case, so I edited it to be complete. 我没有准确写出我的用例,所以我编辑它是完整的。

The most glaring things wrong in this code are: 这段代码中最明显的错误是:

  1. Implicit declaration of myfunction as int myfunction(); 隐式声明myfunctionint myfunction();
  2. Incorrect const-ness of your pointers. 指针的常量不正确。
  3. No return value provided for main() 没有为main()提供返回值

Implicit declaration of myfunction as int myfunction(); 隐式声明myfunctionint myfunction();

This is easy enough to solve, and your compiler should be barking loudly at you when this happens. 这很容易解决,当发生这种情况时,你的编译器应该大声咆哮。 As a legacy feature of C, when a function call is encountered where no formal declaration, either by prototype or definition, is known, the function is assumed to return int and accept a variable number of parameters. 作为C的遗留特性,当遇到函数调用时,如果没有通过原型或定义的正式声明,则假定该函数返回int并接受可变数量的参数。 Therefore in main() your call is assumed to be to a function that looks like this: 因此,在main()中,假定您的调用是一个如下所示的函数:

int myfunction();

Later when the real myfunction is encountered, at a minimum your compiler should scream at you with warning about how the declaration doesn't match the expected type (because by this time it thinks it is int myfunction() ). 稍后当遇到真正的 myfunction时,编译器应该至少尖叫你,并警告声明如何与预期的类型不匹配(因为此时它认为它是int myfunction() )。 Even then, however, the call should still go through, but it is terrible practice to rely on this. 然而,即使这样,呼叫仍然应该通过,但依靠这一点是可怕的做法。 Properly prototype your functions before use. 在使用前正确地将您的功能原型化。


Incorrect data types for all your pointers. 所有指针的数据类型都不正确。

The string literal in your function is not bound to local array space. 函数中的字符串文字未绑定到本地数组空间。 It is a read-only data buffer sitting in a read-only segment somewhere in your program's data blocks. 它是一个只读数据缓冲区,位于程序数据块中的某个只读段中。 The correct declaration is this: 正确的声明是这样的:

const char *test = "mytest";

but that has the ripple effect of requiring changes to the rest of this code, which you'll see in a moment. 但这会产生涟漪效应,需要更改此代码的其余部分,您将在稍后看到。


No return value provided for main() 没有为main()提供返回值

Be definitive in your conclusion of main() . 在你的main()结论中确定。 Apparently C99 allows you to skip this and implementation is supposed to return 0 for you. 显然C99允许你跳过这个,实现应该为你返回0。 Don't give them that joy; 不要给他们那种快乐; seize it yourself. 抓住它自己。


Addressing all of the above... 解决以上所有问题......

#include <stdio.h>

void myfunction(const char** in);

int main()
{
    const char *result = NULL;
    myfunction(&result);
    printf("in main() %p : %s\n", result, result);
    return 0;
}

void myfunction(const char** in) 
{
    const char* test = "mytest";
    printf("in myfunction() %p : %s\n", test, test);
    *in = test;
}

Output (varies by implementation) 输出 (因实施而异)

in main() 0x8048580 : mytest
in myfunction() 0x8048580 : mytest

See it live . 现场观看

It looks good to me. 它对我来说很好看。 May I suggest giving it a prototype or moving your myfunc() definition before main() . 我可以建议给它一个原型或在main()之前移动你的myfunc()定义。 Also assigning a value to result when it is declared. 在声明时也为结果赋值。 That will give you a better idea of what is going on if the function is not doing what you expect. 如果函数没有按照您的预期进行操作,那么这将使您更好地了解正在发生的事情。

For some reason, the other answers just pointed out technical detail that's wrong, but failed to notice what is really wrong: You are returning the address of an array on the stack. 出于某种原因,其他答案只是指出了错误的技术细节,但没有注意到真正的错误:你正在返回堆栈中数组的地址。 But when the function returns, accessing that array becomes undefined behavior. 但是当函数返回时,访问该数组将成为未定义的行为。 Other code may freely overwrite the memory, leaving the worst possible garbage in it, or, conversely, writing to the memory behind the returned pointer may trash any vitally important variable of some other, entirely unconnected parts of the code. 其他代码可以自由地覆盖内存,在其中留下最坏的垃圾,或者相反,写入返回指针后面的内存可能会丢弃代码的其他一些完全未连接的部分的任何极其重要的变量。

If you want to return a pointer, you must either return a pointer to a static object, or you must return a pointer to something on the heap. 如果要返回指针,则必须返回指向static对象的指针,或者必须返回指向堆上某些内容的指针。 Here is the static case: 这是static案例:

char* foo() {
    static char staticArray[1024];
    return staticArray;
}

Using static here guarantees that the memory reserved for staticArray[] will remain reserved for it throughout the execution of your program. 在此处使用static确保在程序执行期间为staticArray []保留的内存将保留给它。 There are, however, three downsides of this: 但是,这有三个缺点:

  1. the array size is fixed at compile time 数组大小在编译时是固定的

  2. this is generally not multithreading safe since all threads will use the same globally allocated memory 这通常不是多线程安全的,因为所有线程都将使用相同的全局分配内存

  3. you generally cannot expect the data behind the returned pointer to remain intact across a function call. 您通常不能指望返回指针后面的数据在函数调用中保持不变。 Consider this code: 考虑以下代码:

     void bar() { char* temp = foo(); temp[0] = 7; } void baz() { char* temp = foo(); temp[0] = 3; bar(); //now temp[0] is 7 ! } 

This might be desirable in some rare cases, however, in most it's not. 在一些罕见的情况下,这可能是理想的,但大多数情况下并非如此。

So, if you want to be able to freely use the memory behind the returned pointer, you have to malloc() memory for it (and free() it afterwards, of course). 所以,如果你想能够自由地使用返回指针后面的内存,你必须为它提供malloc()内存(当然还有free() )。 Like this: 像这样:

char* foo(int size) {
    return malloc(size);
}

void baz() {
    char* sevenBytes = foo(7);
    //Do something with seven bytes
    free(sevenBytes);
}

void bar() {
    char* threeBytes = foo(3);
    threeBytes[0] = 3;
    baz();
    assert(threeBytes[0] == 3);    //baz() worked on it's own memory
    free(threeBytes);
}

In the case of string handling, there is a number of handy functions available in the POSIX-2008 standard that do the memory allocation for you, among them strdup() and asprintf() . 在字符串处理的情况下,POSIX-2008标准中有许多方便的函数可以为你做内存分配,其中包括strdup()asprintf() Here are some usage examples: 以下是一些用法示例:

int main() {
    char* hello = strdup("Hello");
    char* greeting;
    if(0 > asprintf(&greeting, "%s World!\nMemory for hello was allocated at %llx", hello, (long long)hello)) {
        //error handling
    }
    printf(greeting);
    free(hello);
    free(greeting);
}

This will print something like: 这将打印如下:

Hello World!
Memory for hello was allocated at c726de80

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

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