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

将缓冲区(char*)传递给C中的函数,c,memory,size,buffer,allocation,C,Memory,Size,Buffer,Allocation,我正在将一个缓冲区(char*)传递给C中的一个函数 在函数内部,我为缓冲区分配内存并附加一个字符串(来自虚拟服务器的响应)。在函数内部打印时,字符串显示为从服务器发送 当尝试从函数外部读取缓冲区时,我没有得到所需的结果: a、 //char*server_message;//不工作,错误::分段错误(堆芯转储) b、 //char*server_message=calloc((缓冲区大小)+1,sizeof(char));//不工作,未生成错误,下面服务器_消息的printf打印空值::==>

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

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

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

a、 //char*server_message;//不工作,错误::分段错误(堆芯转储)

b、 //char*server_message=calloc((缓冲区大小)+1,sizeof(char));//不工作,未生成错误,下面服务器_消息的printf打印空值::==>服务器_消息::|124;||

c。char*server_message=calloc((1000*BUFFER_SIZE)+1,sizeof(char));//分配超过需要的内存工作::==>服务器消息::| | 2016-03-08 12:20:13您好||

我根本不喜欢选项c,因为我分配的内存比我需要的要多。 出于测试目的,缓冲区大小当前设置为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);
以下是写入到服务器的功能代码:

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);
}
void write_to_server(int file_描述符、char*消息、char*服务器消息)
{
char*msg=strcat(消息“\n”);
int n_bytes=write(文件描述符,msg,strlen(msg)+1);
如果(n_字节0)
{
n_总读取次数+=n_读取次数;
tmp_消息返回[n_读取]='\0';
/*
char*strcat(char*destination,const char*source);
将源字符串的副本追加到目标字符串。
目标中终止的空字符被源的第一个字符覆盖,
并且在由目标中的两个字符串串联而成的新字符串的末尾包含一个空字符。
*/
服务器消息=strcat(服务器消息,tmp消息返回);
//void*realloc(void*ptr,size\u t size);
/*
char*new\u message\u back=realloc(服务器消息,n\u总读取+(缓冲区大小*大小(char));
if(新消息返回==NULL)
{
perror(“从服务器接收字节时无法为服务器_消息分配内存”);
免费(tmp_消息返回);
返回;
}
服务器消息=新消息返回;
*/
server_message=realloc(server_message,n_total_read+(缓冲区大小*大小(字符));
服务器消息[n\u总计\u读取]='\0';
如果(调试模式)
printf(“\n读取%d(%d总计),大小::%zu===>|%s |\t |%s |\n”,n|u读取,n|u读取,strlen(服务器消息),服务器消息,tmp消息返回);
}
服务器消息=realloc(服务器消息,总读取次数);
如果(调试模式)
{
printf(“\n\n\n\n--read总计%d,大小::%zu\n”,n_total_read,strlen(server_message));
printf(“\n\n服务器消息::%s\n\n”,服务器消息);
}
免费(tmp_消息返回);
//免费(信息返回);
}

我不确定,但我认为您的问题是,您希望函数更改参数“Server\u message”。Server_消息是一个char数组(==char*)——但当让函数更改参数时,必须传递一个指向参数的指针

因此,与此相反: 将\写入\服务器(客户端\套接字、消息、服务器\消息); 试试这个: 将\写入\服务器(客户端\套接字、消息和服务器\消息)

函数参数应该是char**Server\u message,编译时也需要对代码进行一些更改


这可能会有所帮助。

在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;
}

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

write_to_server(client_socket, message, &server_message);
我提到我面临的困难是这一行:

(*p_服务器消息)[n_总读取量]='\0'

我必须添加括号,否则会产生::分段错误(核心转储)

现在,只有初始化的缓冲区(我的问题中的案例a)的问题仍然存在:

该函数的新代码为::

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);
}

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

C是按值传递的,即使对于指针也是如此。您正在为参数赋值。如果要修改调用函数中的变量,需要向它们传递指针。指针没有什么特别之处。这个:“void write_to_server(int file_descriptor,char*message,char*server_message)”不能返回char*缓冲区。@molbdnilo,是的,但是char*server_message不是已经是指针了吗?@MartinJames,这个函数不返回任何东西(返回类型为void),但是它不应该能够更改/操作作为指针/引用传递给它的任何参数吗?是的,我尝试过,但是我很难在函数中解引用char**并在解引用的指针上使用malloc(realloc等)。你能举个例子吗?这是正确的,但是如果你能解释为什么第一个是未定义的行为(按值传递),那就太好了。@RogerTannous你可以传递一个指针ba值(第一种情况)或者你可以传递一个指向指针的指针(第二种情况)。@MichaelWalz谢谢你的解释。好的,没错,这是指针的值,但这是指针变量指向的内存缓冲区的地址(指针值)。所以它是缓冲区的引用,缓冲区被认为是通过引用传递的。你同意吗?@RogerTannous或多或少同意。谷歌“c参数值”,你会发现很多解释。@MichaelWalz这是一个观点问题,你的观点是正确的,因为在函数内部,当我们为缓冲区分配内存时(例如,realloc也可能移动内存块…),我们必须考虑缓冲区指针,而不是缓冲区本身。这意味着我们已经将缓冲区指针值传递给了函数。因此,解决方案是传递一个指向该指针的指针char**p\u server\u message。您没有将
server\u message
初始化为
NULL
,因此
*p\u server
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);
}
// if (*p_server_message == NULL)
{
    *p_server_message = calloc(BUFFER_SIZE + 1, sizeof(char));
}