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
)。
注:
- 参考translating your apps guide。
%a
给你一个缩写的工作日名称; %A 完整的工作日名称。 %b
/%B
和月份名称也是如此。 (参见 strftime()
format reference)。
如果您真的想拥有自己的翻译列表,该指南还提供 a clean solution to that。
我正在尝试在手表应用程序上使用区域设置。为此,我首先将 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
)。
注:
- 参考translating your apps guide。
%a
给你一个缩写的工作日名称; %A 完整的工作日名称。%b
/%B
和月份名称也是如此。 (参见strftime()
format reference)。
如果您真的想拥有自己的翻译列表,该指南还提供 a clean solution to that。