- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于字符串,char *
或其他内容,我对C语言有很大的疑问。因此,在这种特殊情况下,我遇到了很大的问题。我想创建一个字符数组,但还不知道它将是多大。我想写这样的东西:
char test[];
char test[num_of_elements];
最佳答案
声明静态字符数组(字符串)
当您知道(或有一个合理的想法,需要将数组的大小)时,只需声明一个足够大的数组即可处理您的输入(即,如果名称不超过25个字符,则可以安全地声明name[26]
。字符串,您始终需要至少为,number of chars to store
, + 1
(对于以空字符结尾的字符)。
如果可能有几个字符超过25个,则声明数组长度比所需的字节数长就可以防止在数组末尾意外写入,这没什么不对。说name[32]
。
让我们在下面声明一个5-characters
数组,并查看信息如何存储在内存中。
char name[5] = {0}; /* always initialize your arrays */
5-contiguous bytes
数组供您使用。例如,您可以可视化初始化为零的5字节内存,如下所示:
+---+---+---+---+---+
name | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+
\
'name' holds the starting address for
the block of memory that is the array
(i.e. the address of the first element
like: 0x7fff050bf3d0)
name
保留“字符字符串”时,实际字符串不能超过
4 字符,因为您
必须以
结尾的字符串结尾为终止符为,即空字符'\0'
(或仅是数字0
,两者都是等效的)name
中,可以通过一次分配字符 来做到这一点:name[0] = 'J';
name[1] = 'o';
name[2] = 'h';
name[3] = 'n';
name[4] = 0; /* null-terminate. note: this was already done by initialization */
+---+---+---+---+---+
name | J | o | h | n | 0 | /* you actually have the ASCII value for */
+---+---+---+---+---+ /* each letter stored in the elements */
strcpy
,strncpy
,memcpy
,或者通过从文件流中读取信息,或者通过使用fgets
,getline
的文件描述符读取信息,或者使用简单的loop
和index variable
进行分配,或者使用一种字符串格式化功能,例如sprintf
等。例如,您可以使用以下任一方法完成相同的操作:/* direct copy */
strcpy (name, "John");
strncpy (name, "John", 5);
memcpy (name, "John", sizeof "John"); /* include copy of the terminating char */
/* read from stdin into name */
printf ("Please enter a name (4 char max): ");
scanf ("%[^\n]%*c", name);
strncpy
(最后一个将用作0
字符,然后使用null-terminating
,则需要手动终止,否则将字符串与strncpy (name, "John", 4);
一起终止)将没有有效的字符串(如果您在需要字符串的地方使用name[4] = 0;
,则将有一个不终止的char数组,这将导致undefined behavior
。)name
是什么,以及它与null-terminated string
的不同之处。认真地说,现在就停止学习吧,这是C语言的基础。(如果它不以array of characters
字符结尾-它不是c字符串。null-terminating
中声明。char *name = NULL; /* declare a pointer, and initialize to NULL */
name = malloc (5 * sizeof *name); /* allocate a 5-byte block of memory for name */
if (!name) { /* validate memory was allocated -- every time */
fputs ("error: name allocation failed, exiting.", stderr);
exit (EXIT_FAILURE);
}
/* Now use name, just as you would the statically declared name above */
strncpy (name, "John", 5);
printf (" name contains: %s\n", name);
free (name); /* free memory when no longer needed.
(if reusing name, set 'name = NULL;')
*/
stdlib.h
不会初始化它分配的内存的内容。如果要用零初始化新的内存块(就像我们对静态数组所做的那样),请使用malloc
而不是calloc
。您还可以使用malloc
,然后也调用malloc
。memset
。您可以使用realloc
重新分配由realloc
创建的原始内存块。 malloc
本质上会创建一个新的内存块,将内存从您的旧块复制到新的内存块,然后释放旧的内存块。由于旧的内存块已释放,因此您想使用临时指针进行重新分配。如果重新分配失败,您仍然可以使用原始的内存块。realloc
的任何调用中添加尽可能少的内存。通常看到的标准方案是从一些初始分配开始,然后在每次用尽时重新分配该数量的两倍。 (这意味着您需要跟踪当前分配了多少内存)。realloc
引用"
)。然后它将分配空间来容纳字符串,然后重新分配以将更多文本附加到原始字符串的末尾。最后,它将在退出之前释放所有正在使用的内存:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
if (argc < 2) { /* validate input */
fprintf (stderr, "error: insufficient input. usage: %s \"name\"\n",
argv[0]);
return 1;
}
size_t len = strlen (argv[1]); /* length of input */
size_t sz_mem = len + 1; /* memory required */
char *name = malloc (sz_mem * sizeof *name); /* allocate memory for name */
if (!name) { /* validate memory created successfully or throw error */
fputs ("error: name allocation failed, exiting.", stderr);
return 1;
}
printf ("\n allocated %zu bytes of memory for 'name'\n", sz_mem);
memset (name, 0, sz_mem); /* initialize memory to zero (optional) */
strncpy (name, argv[1], sz_mem); /* copy the null-terminator as well */
printf (" name: '%s' (begins at address: %p)\n", name, name);
/* realloc - make name twice as big */
void *tmp = realloc (name, 2 * sz_mem); /* use a temporary pointer */
if (!tmp) { /* check realloc succeeded */
fprintf (stderr, "error: virtual memory exhausted, realloc 'name'\n");
return 1;
}
memset (tmp + sz_mem, 0, sz_mem * sizeof *name); /* zero new memory */
name = tmp; /* assign new block to name */
sz_mem += sz_mem; /* update current allocation size */
printf (" reallocated 'name' to %zu bytes\n", sz_mem);
strncat (name, " reallocated", sizeof " reallocated");
printf ("\n final name : '%s'\n\n", name);
free (name);
return 0;
}
$ ./bin/arraybasics "John Q. Public"
allocated 15 bytes of memory for 'name'
name: 'John Q. Public' (begins at address: 0xf17010)
reallocated 'name' to 30 bytes
final name : 'John Q. Public reallocated'
"
之类的内存错误检查器来验证您的内存使用是否正确。 (没有任何借口,这样做很简单)只需键入valgrind
$ valgrind ./bin/arraybasics "John Q. Public"
==19613== Memcheck, a memory error detector
==19613== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19613== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19613== Command: ./bin/arraybasics John\ Q.\ Public
==19613==
allocated 15 bytes of memory for 'name'
name: 'John Q. Public' (begins at address: 0x51e0040)
reallocated 'name' to 30 bytes
final name : 'John Q. Public reallocated'
==19613==
==19613== HEAP SUMMARY:
==19613== in use at exit: 0 bytes in 0 blocks
==19613== total heap usage: 2 allocs, 2 frees, 45 bytes allocated
==19613==
==19613== All heap blocks were freed -- no leaks are possible
==19613==
==19613== For counts of detected and suppressed errors, rerun with: -v
==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
==19613== HEAP SUMMARY:
==19613== in use at exit: 0 bytes in 0 blocks
==19613== total heap usage: 2 allocs, 2 frees, 45 bytes allocated
valgrind yourprogramexe
:==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
关于c - char数组的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32442600/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!