使用纯C(和C预处理器)我想创建一个包含长度参数的字符串缓冲区,这样我就可以轻松地传递它,任何在其上运行的函数都可以这样做而不会有写过去的危险结束。这很简单:
typedef struct strbuf_t_ {
int length;
char str[1];
} strbuf_t;
但是如果我想在堆栈上使用一个小的空间来格式化一些输出文本,那么在堆栈上分配strbuf_t
并不是一种简单的方法。我想要的是一些允许我这样做的聪明的宏:
STRBUF(10) foo;
printf("foo.length = %d\n", foo.length); // outputs: foo.length = 10
strncpy(foo.str, "this is too long", foo.length);
不幸的是,我似乎无法做到这一点。我提出的最好的是:
#define STRBUF(size, name) \
struct {\
strbuf_t buf;\
char space[size - 1];\
char zero;\
} name ## _plus_space_ = { .buf={.length=size}, .space="", .zero='\0'};\
strbuf_t *name = &name ## _plus_space_.buf
int main(void)
{
STRBUF(10, a);
strncpy(a->str, "Hello, world!", a->length);
printf("a->length = %d\n", a->length); // outputs: a->length = 10
puts(a->str); // outputs: Hello, wor
}
这符合我列出的所有要求,但a
是一个指针,而不是结构本身,分配肯定不直观。
有没有人想出更好的东西?
答案 0 :(得分:1)
我认为你已经非常接近解决方案了。只需在结构中保留function MyCtrl($scope, $rootScope) {
$rootScope.name = 'Superhero';
}
function ChildCtrl($scope, $rootScope) {
$rootScope.debug = '';
$scope.$watch('name', function(newVal, oldVal) {
$scope.debug += " value changed...";
});
}
并通过char-array分配它。为了在字符串的末尾保存尾随零,只需为该大小分配一个额外的字符,并用零初始化整个数组。
char*
答案 1 :(得分:1)
也许如下。使用对齐的VLA分配内存,然后重叠。
typedef struct strbuf_t_ {
int length;
char str[];
} strbuf_t;
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdalign.h>
int main(void) {
char *s = "Hello";
size_t length = strlen(s);
size_t n = sizeof (strbuf_t) + length + 1;
_Alignas(strbuf_t) unsigned char mem[n];
strbuf_t *xx = (strbuf_t*) mem;
xx->length = length;
memcpy(xx->str, s, n+1);
printf("int:%zu s:%zu n:%zu mem:%zu\n",
sizeof xx->length, sizeof (strbuf_t), n, sizeof mem);
return 0;
}
输出
int:4 s:4 n:6 mem:10
注意:C99允许最后struct
成员的无限数组计数为[]