C嵌套传递引用内存错误

时间:2018-02-06 08:02:27

标签: c

目标

这是我想要做的,我想创建一个用户列表,并用默认值填充所有信息。然后我想将该列表传递给一个函数,该函数将遍历所有用户并将每个用户解析为一大串数据以返回给用户。

错误

当我循环遍历结构数组时,没有任何值正确地添加到字符串中。我是c的新手,但我知道我没有在引用调用中的某处正确处理我的内存。是的,我确实希望通过引用传递我的所有值,我正在处理的其他代码需要它只是我遇到的问题的简化版本。

守则

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// A simple struct to hold user data
struct user_data
{

  int id;
  int age;

};

// Fill the user with blank information
struct user_data get_blank_user()
{

  struct user_data temp_user;
  temp_user.id = 0;    
  temp_user.age = 0;
  return temp_user;

}

// Turn a structure into a string
void user_struct_to_string(struct user_data *input_user, char **return_data)
{

  // Hold the user id and age
  char user_id[10];
  char user_age[10];

  // print the data into the char arrays
  sprintf(user_id, "{%d,", input_user->id);
  sprintf(user_age, "%d}", input_user->age);

  // Clear all data that was inside the string
  memset(*return_data, 0, sizeof(return_data));

  // copy all the data into the return data
  strcat(*return_data, user_id);
  strcat(*return_data, user_age);

}    

// Turn a array of structures into a large string
void get_all_users_string(struct user_data **input_users, int number_of_users, char **return_data)
{

  char *string_holder = malloc(100 * sizeof(char));
  int i;

  // Loop through all users and add there string of data to the list
  for(i = 0; i < number_of_users; i++)
  {
    // If you are not the first user add a comma before you add to the string
    if (i > 0)
      strcat(*return_data, ",\0");

    // ERROR here after first loop
    user_struct_to_string(&input_users[i], &string_holder);

    // Add the current users string data to the return data
    strcat(*return_data, string_holder);

  }

}

int main()
{

  int i;
  int number_of_users = 10;
  char *user_string = malloc(256 * sizeof(char));

  // Create a dynamic array of users
  struct user_data *users = malloc(number_of_users * sizeof(struct user_data));

  // Fill each user with blank data
  for(i = 0; i < number_of_users; i++)
    users[i] = get_blank_user();

  // Print out a test to prove the function works
  user_struct_to_string(&users[4], &user_string);
  printf("User struct as string: %s\n", user_string);

  // Print user data for test
  for(i = 0; i < number_of_users; i++)
    printf("User id: %d\tUser age: %d\n", users[i].id, users[i].age);

  // Parse all users data into one string
  get_all_users_string(&users, number_of_users, &user_string);
  printf("End string: %s\n", user_string);

  return 0;
}

结果

User struct as string: {0,0}
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
User id: 0      User age: 0
End string: {0,0}{26071328,0},{1879764480,-943433287},{925474080,32764},{0,0},{4196752,0},{1587521584,32641},{0,0},{925474088,32764},{0,1},{4196429,0}

一如既往地感谢任何花时间阅读/帮助线程的人。

3 个答案:

答案 0 :(得分:2)

这不符合您的期望:

memset(*return_data, 0, sizeof(return_data));

sizeof将评估指针大小,而不是字符串的大小。您需要将字符串的长度传递给该函数。

您还应该使用strncat并传递return_data的长度。

同时将sprintf替换为snprintf并传递user_id的长度。

答案 1 :(得分:2)

这里有几个问题,但为了避免这种情况,我会这么做 试着指出你正确的方向。

user_struct_to_string的第二个参数应该是char *因为 在调用之前在函数外部分配字符串。

void user_struct_to_string(struct user_data*, char* );
只有在内部分配字符串时才需要char** user_struct_to_string()以便返回新的地址 已分配字符串给调用者。

所以电话会是

user_struct_to_string(&input_users[i], string_holder); 

(将最大长度传递给函数也是明智的,以避免 通过string_holder指向的大小)

在你的功能中写下

memset(*return_data, 0, sizeof(return_data)); 
在原始情况下,

不能做你想要的,sizeof(return_data) 当它是一个char **给出指针的大小,而不是长度 分配字符串。这就是为什么它通过最大长度是很方便的 为函数分配了字符串。

void user_struct_to_string(struct user_data*, char* return_data, size_t maxLen )
{
...
  memset(return_data, 0, maxLen); 
...
}

虽然更好的方法是将第一个字节string_holder设置为\ 0 然后将其传递给函数

BTW你用user_id和user_age创建数组,为什么不直接写 它进入你想要返回的字符串?

void user_struct_to_string(struct user_data*, char* return_data )
{
...
  sprintf( return_data, "{%d,%d}", input_user->id, input_user->age);
}    

答案 2 :(得分:1)

您的代码唯一的问题是行 -

user_struct_to_string(&input_users[i], &string_holder);

该函数需要struct user_data*,但您传递struct user_data**。编译器应该已经警告过你。您可以查看警告。

无论如何,要修复它,您可以将线路更改为 -

user_struct_to_string(&((*input_users)[i]), &string_holder);

您可以在Ideone上看到工作演示。