C 复制到 const char *
C Copying to a const char *
我有一个项目,我得到了一个头文件,其中包含:
typedef struct User_struct {
const char *name;
Friends amigos;
} User;
Friends 是另一个不在我的问题范围内的结构
在我需要创建的源文件中,我创建了一个结构体和随后的全局变量:
typedef struct UserList{
User *user;
struct UserList *next;
}UserList;
static UserList *users;
有一个初始化函数create_amigonet
,我在其中分配内存给users
,另一个分配给users->user
。我的问题是这个函数:
void addUser( const char *name )
{
UserList *new_users;
UserList *iter;
if(users->user->name == NULL)
{
users->user->name = malloc(strlen(name));
strncpy((users->user->name,name,strlen(name));
return;
}
for(iter = users; iter != NULL; iter = iter->next)
{
if(iter->user->name == name)
return;
}
new_users = malloc(sizeof(UserList));
if(new_users != NULL)
{
new_users->user = malloc(sizeof(User));
new_users->user->name = malloc(sizeof(name)+1);
strncpy(new_users->user->name,name,sizeof(name)+1);
new_users->user->amigos = NULL;
new_users->next = users;
users = new_users;
}
return;
}
我需要将 const char *
复制到 const char *
,并且不允许更改 User 结构或函数的定义。我不确定我应该如何 copy/initialize 我结构中的任何节点。我可以更改 UserList
,这是我作为 "users".
的链表创建的结构
这将导致一个问题:
users->user->name = malloc(strlen(name));
strncpy((users->user->name,name,strlen(name));
看来你不了解空终止。假设您稍后想要读出 users->user->name
。您如何知道名称何时结束?您没有在任何地方保存信息 strlen(name)
。
因此,C 中的字符串在其末尾有一个标记。该标记是一个空字节(值 0
的字节)。然后,字符串处理函数知道字符串的结尾在哪里(通常是分配的内存的结尾)。
所以你需要分配一个额外的字节,并使用适当的复制功能:
users->user->name = malloc(strlen(name) + 1);
strcpy(users->user->name, name);
根据经验,永远不要使用 strncpy
。 strcpy
或 snprintf
函数更合适。 strncpy
是昔日的遗迹。
您稍后在程序中有一个类似的(但更糟糕的是,因为您在没有真正理解 sizeof
的作用的情况下误用了 sizeof
)。希望您现在也可以在阅读我的回答后解决这个问题。
I need to copy a const char * into a const char *,
您需要停止将指针视为 "containing" 任何东西。指针指向内存的其他部分,这些部分本身必须存在。
您需要将一些字节从一个地方复制到另一个地方,那里有指向两个位置的指针。
现在,您无法通过 const char *
写入某个位置。这就是 const
的用途。但是,该位置在只读内存中 而不是 :您只是 malloc 了它。所以写的位置肯定是安全的。您只需要重新安排代码,以便将非常量指针传递给写入函数。一种方法是:
char *new_name = malloc(strlen(name) + 1);
strcpy(new_name, name);
users->user->name = new_name;
另一种方式,如果您使用的是 POSIX 系统,则为:
users->user->name = strdup(name);
效果相同
我有一个项目,我得到了一个头文件,其中包含:
typedef struct User_struct {
const char *name;
Friends amigos;
} User;
Friends 是另一个不在我的问题范围内的结构
在我需要创建的源文件中,我创建了一个结构体和随后的全局变量:
typedef struct UserList{
User *user;
struct UserList *next;
}UserList;
static UserList *users;
有一个初始化函数create_amigonet
,我在其中分配内存给users
,另一个分配给users->user
。我的问题是这个函数:
void addUser( const char *name )
{
UserList *new_users;
UserList *iter;
if(users->user->name == NULL)
{
users->user->name = malloc(strlen(name));
strncpy((users->user->name,name,strlen(name));
return;
}
for(iter = users; iter != NULL; iter = iter->next)
{
if(iter->user->name == name)
return;
}
new_users = malloc(sizeof(UserList));
if(new_users != NULL)
{
new_users->user = malloc(sizeof(User));
new_users->user->name = malloc(sizeof(name)+1);
strncpy(new_users->user->name,name,sizeof(name)+1);
new_users->user->amigos = NULL;
new_users->next = users;
users = new_users;
}
return;
}
我需要将 const char *
复制到 const char *
,并且不允许更改 User 结构或函数的定义。我不确定我应该如何 copy/initialize 我结构中的任何节点。我可以更改 UserList
,这是我作为 "users".
这将导致一个问题:
users->user->name = malloc(strlen(name));
strncpy((users->user->name,name,strlen(name));
看来你不了解空终止。假设您稍后想要读出 users->user->name
。您如何知道名称何时结束?您没有在任何地方保存信息 strlen(name)
。
因此,C 中的字符串在其末尾有一个标记。该标记是一个空字节(值 0
的字节)。然后,字符串处理函数知道字符串的结尾在哪里(通常是分配的内存的结尾)。
所以你需要分配一个额外的字节,并使用适当的复制功能:
users->user->name = malloc(strlen(name) + 1);
strcpy(users->user->name, name);
根据经验,永远不要使用 strncpy
。 strcpy
或 snprintf
函数更合适。 strncpy
是昔日的遗迹。
您稍后在程序中有一个类似的(但更糟糕的是,因为您在没有真正理解 sizeof
的作用的情况下误用了 sizeof
)。希望您现在也可以在阅读我的回答后解决这个问题。
I need to copy a const char * into a const char *,
您需要停止将指针视为 "containing" 任何东西。指针指向内存的其他部分,这些部分本身必须存在。
您需要将一些字节从一个地方复制到另一个地方,那里有指向两个位置的指针。
现在,您无法通过 const char *
写入某个位置。这就是 const
的用途。但是,该位置在只读内存中 而不是 :您只是 malloc 了它。所以写的位置肯定是安全的。您只需要重新安排代码,以便将非常量指针传递给写入函数。一种方法是:
char *new_name = malloc(strlen(name) + 1);
strcpy(new_name, name);
users->user->name = new_name;
另一种方式,如果您使用的是 POSIX 系统,则为:
users->user->name = strdup(name);
效果相同