Closed. This question is off-topic. It is not currently accepting answers. Learn more。
想改进这个问题吗?Update the question所以堆栈溢出的值小于aa>。
三年前关闭。
我很难在我的pebble watch应用程序中找到一个奇怪的错误。我怀疑是记错了,但我找不到我的错误。我有一个字符串数组,当我调用
我有一个头文件,它将三个变量声明为外部变量,因此它们是全局的。
这三个变量在main.c中修改,但在其他c文件中使用。下面是我的main.c文件的一个示例,我在其中设置字符串数组
这似乎工作得很好,我检查了for循环中的每个字符串,最后一个字符总是以空结尾的字节,前面的一个是句点(句子的结尾)。我不在任何地方修改这些值,而且直到程序结束时才释放它们(因为它们应该存在于程序的生命中)。
我创建了一个具有动态条目数的菜单(在本例中是6个),每个菜单都有
当按下每个菜单项时,它应该在滚动层中显示
最后一部分有时是不同的,解码字节和位置根据字符串而改变。请注意,在日志中,对于最后三个空白菜单项总是会产生一些错误,只有在前三个菜单项出现错误的时候,即使滚动层不是空白的并且显示了正确的文本(对于前三个菜单项,有时它会毫无问题地打印到日志中)。
我在不同的地方尝试过
也许我遗漏了一些很简单的东西,但我找不到我的错误。我相信我已经为
分配内存,但立即用标记指针覆盖指针。然后,在另一个类似的代码块中,重写了这些点所指向的字符串。自从内存被重新分配以来,您可能是“幸运的”,而之前的字符串内存仍然没有被其他进程所影响。实际上,您最终还是释放了这个字符串缓冲区,而没有复制标记。
我想你需要一个
类似地,对于teasers代码块。
我还注意到,您通过
想改进这个问题吗?Update the question所以堆栈溢出的值小于aa>。
三年前关闭。
我很难在我的pebble watch应用程序中找到一个奇怪的错误。我怀疑是记错了,但我找不到我的错误。我有一个字符串数组,当我调用
menu_layer = menu_layer_create(bounds);
时,它似乎在某种程度上损坏我的字符串。我在下面更详细地解释。错误的描述以粗体显示。我有一个头文件,它将三个变量声明为外部变量,因此它们是全局的。
//externs.h
#ifndef EXTERNS_H
#define EXTERNS_H
// These global variables are accessible by all source files. Modified in main.c
extern int str_count;
extern char **str_titles;
extern char **str_teasers;
#endif
这三个变量在main.c中修改,但在其他c文件中使用。下面是我的main.c文件的一个示例,我在其中设置字符串数组
str_titles
和str_teasers
。结构info
包含两个很长但用分隔符|
分隔的字符串。我将这些字符串复制到一个临时缓冲区s_buffer
中,并用strtok
对它们进行解析,将每个新字符串保存到字符串数组中。这似乎工作得很好,我检查了for循环中的每个字符串,最后一个字符总是以空结尾的字节,前面的一个是句点(句子的结尾)。我不在任何地方修改这些值,而且直到程序结束时才释放它们(因为它们应该存在于程序的生命中)。
我创建了一个具有动态条目数的菜单(在本例中是6个),每个菜单都有
str_titles
中6个字符串之一的标题。这里没有问题。我可以在程序中随时迭代并APP_LOG
这个字符串数组。当按下每个菜单项时,它应该在滚动层中显示
str_teasers
中的较长字符串。它只对前三个菜单项可靠地执行此操作。最后三个总是空的。尝试在这里用APP_LOG
迭代和打印字符串数组,会在pebble日志使用的python框架中产生一系列错误,并且总是以如下内容结尾:UnicodeDecodeError: 'utf8' codec can't decode byte 0x98 in position 0: invalid start byte
最后一部分有时是不同的,解码字节和位置根据字符串而改变。请注意,在日志中,对于最后三个空白菜单项总是会产生一些错误,只有在前三个菜单项出现错误的时候,即使滚动层不是空白的并且显示了正确的文本(对于前三个菜单项,有时它会毫无问题地打印到日志中)。
我在不同的地方尝试过
invalid start byte
打开APP_LOG
,当它失败时,它会在我调用str_teasers
创建菜单后这样做。在我打电话之前,我可以用APP_日志打印所有字符串,没有任何问题。我以为这是堆损坏错误,但在创建层之前和之后,我有可用的堆内存(约8100字节),我的应用程序不会崩溃。也许我遗漏了一些很简单的东西,但我找不到我的错误。我相信我已经为
menu_layer = menu_layer_create(bounds);
正确地分配了内存,所以我根本不明白为什么要修改它。我在下面提供了一个修改后的示例代码以供参考。//main.c
#include "strtok.h"
#include "externs.h"
int str_count;
char **str_titles;
char **str_teasers;
char *s_buffer;
const char delim[1] = "|";
char *token;
typedef struct {
int s_count;
char* s_titles;
char* s_teasers;
} s_info;
s_info info;
// Sample code
str_count = info.s_count;
// Declare arrays of appropriate size
str_titles = malloc(str_count * sizeof(char*));
str_teasers = malloc(str_count * sizeof(char*));
// This creates a copy of the entire string s_titles into s_buffer
int len = strlen(info.s_titles) + 1;
s_buffer = (char *)malloc(len);
strcpy(s_buffer, info.s_titles);
token = strtok(s_buffer, delim); // Get the first token for the titles
// Walk through the other tokens
int counter = 0;
while(token != NULL) {
*(str_titles + counter) = malloc((strlen(token) + 1) * sizeof(char));
*(str_titles + counter) = token;
token = strtok(NULL, delim);
counter++;
}
// This creates a copy of the entire string s_teasers into s_buffer
len = strlen(info.s_teasers) + 1;
s_buffer = (char *)realloc(s_buffer, len);
strcpy(s_buffer, info.s_teasers);
token = strtok(s_buffer, delim); // Get the first token for the teasers
// Walk through the other tokens
counter = 0;
while(token != NULL) {
*(str_teasers + counter) = malloc((strlen(token) + 1) * sizeof(char));
*(str_teasers + counter) = token;
token = strtok(NULL, delim);
counter++;
}
free(s_buffer);
最佳答案
在这个代码块中
// Walk through the other tokens
int counter = 0;
while(token != NULL) {
*(str_titles + counter) = malloc((strlen(token) + 1) * sizeof(char));
*(str_titles + counter) = token;
token = strtok(NULL, delim);
counter++;
}
分配内存,但立即用标记指针覆盖指针。然后,在另一个类似的代码块中,重写了这些点所指向的字符串。自从内存被重新分配以来,您可能是“幸运的”,而之前的字符串内存仍然没有被其他进程所影响。实际上,您最终还是释放了这个字符串缓冲区,而没有复制标记。
我想你需要一个
// Walk through the other tokens
int counter = 0;
while(token != NULL) {
*(str_titles + counter) = malloc((strlen(token) + 1) * sizeof(char));
strcpy(*(str_titles + counter), token); // <<--- here
token = strtok(NULL, delim);
counter++;
}
类似地,对于teasers代码块。
我还注意到,您通过
strcpy
索引,但没有对照提供给您的counter
进行检查,后者用于为字符串指针数组分配内存。关于c - 调用menu_layer时字符串损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36206418/