繁体   English   中英

将缓冲区 (char*) 传递给 C 中的函数

[英]Passing a buffer (char*) to a function in C

我正在将缓冲区 (char*) 传递给 C 中的函数。

在函数内部,我为缓冲区分配内存并附加一个字符串(来自虚拟服务器的响应)。 在函数内部打印时,字符串显示为从服务器发送。

当试图从函数外部读取缓冲区时,我没有得到我需要的结果:

一种。 // char* server_message; // 不工作,错误:: Segmentation fault (core dumped)

// char* server_message = calloc((BUFFER_SIZE) + 1, sizeof(char)); // 不起作用,没有产生错误,下面 server_message 的 printf 打印一个空值:: ==> server_message:: || ||

C。 char* server_message = calloc((1000 * BUFFER_SIZE) + 1, sizeof(char)); // 分配超过需要的内存有效:: ==> server_message:: || 2016-03-08 12:20:13 你好 ||

我根本不喜欢选项 c,因为我分配的内存超出了我的需要。 BUFFER_SIZE 当前设置为 10 以进行测试。

这是调用部分::

write_to_server(client_socket, message, server_message);
free(message);
printf("\n\n==> server_message:: || %s ||\n\n", server_message);

if (server_message != NULL)
    free(server_message);

这是 write_to_server 函数代码:

void write_to_server(int file_descriptor, char* message, char* server_message)
{

    char* msg = strcat(message, "\n");

int n_bytes = write(file_descriptor, msg, strlen(msg) + 1);

if (n_bytes <= 0)
{
    perror("write");
    exit(EXIT_FAILURE);
}

if (DEBUG_MODE) 
    printf("\nsuccessfully written %d bytes to server:: %s", n_bytes, msg);

// char* message_back = calloc(BUFFER_SIZE + 1, sizeof(char));
if (server_message == NULL)
{
    server_message = calloc(BUFFER_SIZE + 1, sizeof(char));
}

if (server_message == NULL)
{
    perror("Could not allocate memory for server_message");
    exit(EXIT_FAILURE);
}

char* tmp_message_back = calloc(BUFFER_SIZE + 1, sizeof(char));

if (tmp_message_back == NULL)
{
    if (DEBUG_MODE)
        perror("Could not allocate memory for tmp_message_back");

    exit(EXIT_FAILURE);
}

int n_read = 0; 
int n_total_read = 0;

while ((n_read = read(file_descriptor, tmp_message_back, BUFFER_SIZE)) > 0)
{
    n_total_read += n_read;
    tmp_message_back[n_read] = '\0';

    /*
    char* strcat(char* destination, const char* source);

    Appends a copy of the source string to the destination string.
    The terminating null character in destination is overwritten by the first character of source, 
    and a null-character is included at the end of the new string formed by the concatenation of both in destination.
    */
    server_message = strcat(server_message, tmp_message_back);

    // void* realloc(void* ptr, size_t size);
    /*
    char* new_message_back = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));

    if (new_message_back == NULL)
    {
        perror("Could not allocate memory for server_message while receiving bytes from server");

        free(tmp_message_back);

        return;
    }

    server_message = new_message_back;
    */
    server_message = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));
    server_message[n_total_read] = '\0';

    if (DEBUG_MODE)
        printf("\nread %d (%d in total), size:: %zu ===> | %s |\t| %s |\n", n_read, n_total_read, strlen(server_message), server_message, tmp_message_back);
}

server_message = realloc(server_message, n_total_read);

if (DEBUG_MODE)
{
    printf("\n\n\n\n-- read %d in total, size:: %zu\n", n_total_read, strlen(server_message));
    printf("\n\nserver_message:: %s\n\n", server_message);
}

free(tmp_message_back);
// free(message_back);
}

在 C 中,参数是按值传递的。 基本上你这样做是期望输出是
Hello world!

void Test(char *ptr)
{
    ptr = malloc(100);   // this modifies ptr but not
                         // somepointer in the main function
    strcpy(ptr, "Hello world!");
}

int main()
{
    char *somepointer;  // somepointer is not initialized and contains
                        // an indetermined value
    Test(somepointer);
                        // here the value of somepointer has not changed

    printf("%s", somepointer);   // here you try to printf a char pointer
                                 // that points to an idetermined location
    return 0;
}

这是未定义的行为,很可能会打印垃圾或崩溃。

你需要的是这个:

void Test(char **ptr)
{
    *ptr = malloc(100);
    strcpy(*ptr, "Hello world!");
}

int main()
{
    char *somepointer;
    Test(&somepointer);   // pass the pointer to sompointer to Test
    printf("%s", somepointer);  // now somepointer points to the memory
                                // mallocd in Test
    return 0;
}

我不确定,但我认为您的问题是,您希望您的函数更改参数“Server_message”。 Server_Message 是一个字符数组 (== char*) - 但是当让函数更改您的参数时,您必须传递一个指向您的参数的指针。

所以代替这个: write_to_server(client_socket, message, server_message); 试试这个: write_to_server(client_socket, message, &server_message);

函数参数应该是 char** Server_message - 代码中的一些更改也是编译所必需的。

也许,这有帮助。

好的,现在我已经将函数 write_to_server 更改为接受 char** p_server_message 并使用以下方法调用它:

write_to_server(client_socket, message, &server_message);

我提到我面临的困难是这一行:

(*p_server_message)[n_total_read] = '\\0';

我不得不添加括号,否则它会产生:: Segmentation fault (core dumped)

现在问题只存在于初始化的缓冲区(我的问题中的情况 a)::

char* server_message;

write_to_server(client_socket, message, &server_message);
free(message);
printf("\n\n==> server_message:: || %s ||\n\n", server_message);

该函数的新代码是::

void write_to_server(int file_descriptor, char* message, char** p_server_message)
{

char* msg = strcat(message, "\n");

int n_bytes = write(file_descriptor, msg, strlen(msg) + 1);

if (n_bytes <= 0)
{
    perror("write");
    exit(EXIT_FAILURE);
}

if (DEBUG_MODE) 
    printf("\nsuccessfully written %d bytes to server:: %s", n_bytes, msg);

// char* message_back = calloc(BUFFER_SIZE + 1, sizeof(char));
if (*p_server_message == NULL)
{
    *p_server_message = calloc(BUFFER_SIZE + 1, sizeof(char));
}

if (*p_server_message == NULL)
{
    perror("Could not allocate memory for p_server_message");
    exit(EXIT_FAILURE);
}

char* tmp_message_back = calloc(BUFFER_SIZE + 1, sizeof(char));

if (tmp_message_back == NULL)
{
    if (DEBUG_MODE)
        perror("Could not allocate memory for tmp_message_back");

    exit(EXIT_FAILURE);
}

int n_read = 0; 
int n_total_read = 0;

while ((n_read = read(file_descriptor, tmp_message_back, BUFFER_SIZE)) > 0)
{
    n_total_read += n_read;
    tmp_message_back[n_read] = '\0';

    /*
    char* strcat(char* destination, const char* source);

    Appends a copy of the source string to the destination string.
    The terminating null character in destination is overwritten by the first character of source, 
    and a null-character is included at the end of the new string formed by the concatenation of both in destination.
    */
    *p_server_message = strcat(*p_server_message, tmp_message_back);

    // void* realloc(void* ptr, size_t size);
    /*
    char* new_message_back = realloc(*p_server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));

    if (new_message_back == NULL)
    {
        perror("Could not allocate memory for p_server_message while receiving bytes from server");

        free(tmp_message_back);

        return;
    }

    *p_server_message = new_message_back;
    */
    *p_server_message = realloc(*p_server_message, n_total_read + (BUFFER_SIZE * sizeof(char)));
    (*p_server_message)[n_total_read] = '\0';

    if (DEBUG_MODE)
        printf("\nread %d (%d in total), size:: %zu ===> | %s |\t| %s |\n", n_read, n_total_read, strlen(*p_server_message), *p_server_message, tmp_message_back);
}

*p_server_message = realloc(*p_server_message, n_total_read);

if (DEBUG_MODE)
{
    printf("\n\n\n\n-- read %d in total, size:: %zu\n", n_total_read, strlen(*p_server_message));
    printf("\n\np_server_message:: %s\n\n", *p_server_message);
}

free(tmp_message_back);
// free(message_back);
}

那么为什么它仍然为未初始化的缓冲区产生分段错误?

如果我在函数内部分配和初始化内存(使用 calloc),无论缓冲区是否已经初始化,我都可以解决这个问题。

通过取消注释该行::

// if (*p_server_message == NULL)
{
    *p_server_message = calloc(BUFFER_SIZE + 1, sizeof(char));
}

但我无法理解这背后的原因。

暂无
暂无

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

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