为sprintf问题分配内存?

时间:2010-12-29 17:52:15

标签: c

问题是我不知道字符串会有多长,所以我不知道应该为我的数据分配多少......

char *Data = malloc(1024*1024);  //???????
sprintf(Data, "%s %s", Data1, Data2);

Data1和Data2的大小不时变化......从非常长到非常小 我想知道是否有没有分配内存或其他东西使用sprintf,因为分配的内存有时会很小..

感谢

6 个答案:

答案 0 :(得分:6)

许多C运行时库(例如,GNU的glibc和FreeBSD(以及NetBSD和OpenBSD和OS X的)libc)提供asprintf,它将mallocsprintf组合到一个调用中

char *Data = NULL;
asprintf(&data, "%s %s", Data1, Data2);

假设返回值表示成功,则为字符串动态分配了足够的空间,不再使用时应该free

答案 1 :(得分:5)

由于data1和data2似乎是字符串,所以只需使用strlen()并仅分配实际需要的内存量。

char *data = malloc(sizeof(char) * (strlen(data1) + strlen(data2) + 1));

答案 2 :(得分:4)

而不是sprintf()使用永远不会溢出缓冲区的snprintf()(你告诉它缓冲区有多大)。 snprintf()还会告诉您缓冲区需要多大才能避免截断结果。

请注意,MSVC没有snprintf(),但包含类似的_snprintf()。但是,该功能与标准至少有2个不同之处:

  • 可能会使结果无法终结
  • 如果它截断
  • ,它不会告诉你需要多大的缓冲区

如果您正在使用MSVC,则可能需要考虑使用Holger Weiss' snprintf() implementation(具有自由许可证)。

答案 3 :(得分:1)

不可能。您始终必须分配sprintf / printf

使用的缓冲区

答案 4 :(得分:0)

简短的回答是否定的。

...但是您不需要每次运行代码都进行分配。根据您的程序是否是多线程的,这部分代码的运行频率以及您期望的最大可能字符串的大小,您最好分配一个“最大可能大小”的缓冲区一次并使用像snprintf这样的安全版sprintf来填充它。 (防止超支)。或者,如果您需要的大小超过当前缓冲区大小,您可以有条件地重新分配缓冲区。

例如,如果您使用的是C ++且上面的代码位于方法内,则可以将数据分配行更改为:

static char *Data = malloc(1024*1024);

方法中使用的static关键字承诺您的局部变量只会被初始化一次 - 第一次调用该行并且将超出该方法调用的范围。

如果您正在使用C,那么您的缓冲区可能是全局的(我不是这个的粉丝),或者您可以将指针传递给本地范围的数据缓冲区。我确信真正的C程序员对如何做这类事情有更好的建议。

我知道只有一个巨大的缓冲区,你几乎从未充分利用它似乎效率低下,但事实证明,对于大多数应用程序来说,分配的开销远远大于堆耗尽的问题。空间。

答案 5 :(得分:0)

为什么不将strlen函数用于字符串大小?

char *buf = malloc(strlen(Data1) + strlen(Data2) + 2); // 2 for space and \0
sprintf(buf, "%s %s", Data1, Data2);

这解决了您需要在运行时确定Data1和Data2的大小的问题。