C中多维字符串数组的内存溢出

Memory overflow with multidimensional arrays of string in C

我正在尝试在手表应用程序上使用区域设置。为此,我首先将 locale 字符串存储在具有以下定义的变量中:

static char locale[] = "en_US";

我有一个包含每种语言的 "packages" 的多维数组。这是一个示例定义:

static const char *locale_packages[][2][12] = {
    {{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, { "Jan", "Febr", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"}},         // EN = 0
    {{"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"}, { "Janv", "Fevr", "Mars", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"}}   // FR = 1
};

我还定义了数组来存储我的语言的日期字符串。它们的定义如下:

static char *day_of_week[7];
static char *month_of_year[12];

我的想法是:如果语言环境是 fr_FR,我想用法语显示 Wednesday 的翻译,那么我只使用 day_of_week[3].

终于用上了这个功能

static void load_locale(char *locale_string, char *day_var[], char *month_var[]) {
  static int locale_int;
  locale_int = locale_number(locale_string); 
  // locale_number returns the array position of my locale. 
  // For instance, locale_number("en_US") will return '0'
  static char *selected_locale[2][12];
  memcpy(selected_locale, locale_packages[locale_int], sizeof locale_packages[locale_int]);
  memcpy(day_var, selected_locale[0], sizeof selected_locale[0]);
  memcpy(month_var, selected_locale[1], sizeof selected_locale[1]);
}

最后,我 运行:

load_locale(locale, day_of_week, month_of_year);

然而,尽管编译成功,应用程序在 'loading locales' 后立即崩溃。我能够 return 日志中的一些值,并且我尝试的每个测试都有效,所以这意味着我的函数 'does what it should',但似乎存在内存溢出或类似的问题。

有人看到我犯的错误了吗?我在 C 方面不是很有经验,这是我第一次使用多维数组。

这段代码有问题:

memcpy(day_var, selected_locale[0], sizeof selected_locale[0]);

如果您实际上将 static char *day_of_week[7]; 作为 day_var 的参数传入,则会导致缓冲区溢出,因为 selected_locale[0] 有 12 个条目。 (7 个指向字符串的指针和 5 个空指针)。

要解决此问题,您需要调整 memcpy 的数量。


注意。 selected_locale 是多余的。您可以直接从 locale_packages[locale_int][0] 复制到 day_var 等等。

如果您保留它,则它不需要是静态的,并且 char 旁边应该有 const

如果您只是想获取本地语言的日期和月份名称,那么您可以使用:

setlocale(LC_ALL, NULL);

char day[10], month[10];
strftime(day, sizeof(day), "%a", time);
strftime(month, sizeof(month), "%b", time);

(其中时间是 struct tm)。

注:

如果您真的想拥有自己的翻译列表,该指南还提供 a clean solution to that