无处不看,他们分配内存,然后才知道他们将填补多少 。
是和否。
struct Friends {
char *firstname;
char *lastname;
};
这一切都取决于你打算如何使用你的结构。有多种方式可以使用struct Friends
。你可以声明结构的静态实例,然后简单地存在字符串的地址分配给您的firstname
和lastname
成员指针,例如:
int main (void) {
Struct Friends friend = {{Null}, {NULL]};
/* simple assignment of pointer address
* (memory at address must remain valid/unchanged)
*/
friend.firstname = argc > 1 ? argv[1] : "John";
friend.lastname = argc > 2 ? argv[2] : "Smith";
printf ("\n name: %s %s\n\n", friend.firstname, friend.lastname);
然而,在大多数情况下,你将要创建的副本该信息并存储firstname
和lastname
成员的字符串副本。在这种情况下,您需要为每个指针分配一个新的内存块,并将每个新块的起始地址分配给每个指针。在这里,你现在知道你的字符串是什么,你只需要为每个字符串的长度分配内存(+1
为NUL终止字符),例如:
int main (int argc, char **argv) {
/* declare static instance of struct */
struct Friends friend = {NULL, NULL};
char *first = argc > 1 ? argv[1] : "John";
char *last = argc > 2 ? argv[2] : "Smith";
/* determine the length of each string */
size_t len_first = strlen (first);
size_t len_last = strlen (last);
/* allocate memory for each pointer in 'friend' */
friend.firstname = malloc (len_first * sizeof *friend.firstname + 1);
friend.lastname = malloc (len_last * sizeof *friend.lastname + 1);
然后,您只需要在每个字符串复制到地址为每个成员:
/* copy names to new memory referenced by each pointer */
strcpy (friend.firstname, first);
strcpy (friend.lastname, last);
最后,一旦您所使用的内存分配完成后,你必须用free
释放内存。 备注:您只能使用free
内存,您以前分配的内存为malloc
或calloc
。切勿盲目地尝试释放未被分配的内存。要释放的成员,所有你需要的是:
/* free allocated memory */
free (friend.firstname);
free (friend.lastname);
简单例子把所有的拼在一起就是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Friends {
char *firstname;
char *lastname;
};
int main (int argc, char **argv) {
/* declare static instance of struct */
struct Friends friend = {NULL, NULL};
char *first = argc > 1 ? argv[1] : "John";
char *last = argc > 2 ? argv[2] : "Smith";
/* determine the length of each string */
size_t len_first = strlen (first);
size_t len_last = strlen (last);
/* allocate memory for each pointer in 'friend' */
friend.firstname = malloc (len_first * sizeof *friend.firstname + 1);
friend.lastname = malloc (len_last * sizeof *friend.lastname + 1);
/* copy names to new memory referenced by each pointer */
strcpy (friend.firstname, first);
strcpy (friend.lastname, last);
printf ("\n name: %s %s\n\n", friend.firstname, friend.lastname);
/* free allocated memory */
free (friend.firstname);
free (friend.lastname);
return 0;
}
始终编译警告启用,例如:
gcc -Wall -Wextra -o bin/struct_dyn_alloc struct_dyn_alloc.c
(如果不使用gcc
,那么你的编译器将有类似的选项)
只要在代码中动态分配内存,运行内存错误检查程序以确保您不会以某种方式滥用分配的内存块,并确认所有内存已被释放。这很容易做到。所有操作系统都有一些类型的检查器。在Linux上,valgrind
是正常的选择。例如:
$ valgrind ./bin/struct_dyn_alloc
==14805== Memcheck, a memory error detector
==14805== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14805== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==14805== Command: ./bin/struct_dyn_alloc
==14805==
name: John Smith
==14805==
==14805== HEAP SUMMARY:
==14805== in use at exit: 0 bytes in 0 blocks
==14805== total heap usage: 2 allocs, 2 frees, 11 bytes allocated
==14805==
==14805== All heap blocks were freed -- no leaks are possible
==14805==
==14805== For counts of detected and suppressed errors, rerun with: -v
==14805== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
'2倍的sizeof(char)的2倍=应1Byte'是'2倍的sizeof(字符*)' - 这取决于平台 –
所有的假设都是错误的。 'malloc(sizeof(Friends))'会分配(至少)'2 * sizeof(char *)' - 介意'*'。它为指针分配空间,而不是字符。如果你想填充一些东西,你将不得不执行额外的分配。 –
非常感谢,我现在明白了! – Scarh