Ich habe eine sehr harte Zeit, einen seltsamen Fehler in meiner Pebble Watch App zu verfolgen. Ich vermute, es ist ein Speicherfehler, aber ich kann meinen Fehler nicht finden. Ich habe eine Reihe von Saiten, und wenn ich menu_layer = menu_layer_create(bounds);
rufe, scheint es irgendwie meine Saite zu verderben. Ich erkläre es unten ausführlicher. Die Beschreibung des Fehlers ist fett formatiert.String Korruption beim Aufruf von Menülayer
Ich habe eine Header-Dateien, die drei Variablen als extern deklariert, so dass sie global sind.
//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
Diese drei Variablen sind in main.c geändert, werden aber in anderen c-Dateien verwendet. Unten ist ein Beispiel meiner main.c Datei, wo ich das Array der Zeichenfolgen str_titles
und str_teasers
setze. Die Struktur info
enthält zwei Strings, die sehr lang sind, aber durch das Trennzeichen |
getrennt sind. Ich kopiere diese Zeichenfolgen in einen temporären Puffer s_buffer
und analysiere sie auseinander mit strtok
und speichere jede neue Zeichenfolge in meinem Array von Zeichenfolgen.
Dies scheint gut zu funktionieren, ich habe jede Zeichenfolge in einer for-Schleife überprüft und das letzte Zeichen ist immer das nullterminierte Byte und das davor ist ein Punkt (Ende des Satzes). Ich ändere diese Werte nirgendwo anders, und ich befreie sie nicht bis zum Ende meines Programms (weil sie für das Leben des Programms existieren sollten).
Ich erstelle ein Menü mit einer dynamischen Anzahl von Einträgen (in diesem Fall 6), und jedes Menü hat den Titel einer der 6 Zeichenfolgen innerhalb str_titles
. Hier gibt es keine Probleme. Ich kann durch und APP_LOG
dieses Array von Strings ohne Probleme jederzeit in meinem Programm durchlaufen.
Wenn jeder Menüeintrag gedrückt wird, sollte die längere Zeichenfolge von str_teasers
in einer Bildlaufebene angezeigt werden. Dies geschieht zuverlässig nur für die ersten drei Menüpunkte. Für die letzten drei ist es immer leer. das Array von Strings hier mit APP_LOG
erzeugt eine Litanei von Fehlern in der Python-Framework mit den Kies Protokolle und endet immer mit so etwas wie verwendet iterieren Der Versuch, und drucken:
UnicodeDecodeError: 'utf8' codec can't decode byte 0x98 in position 0: invalid start byte
Der letzte Teil invalid start byte
ist manchmal etwas anderes und die Decodierbytes und Position ändert sich basierend auf der Zeichenfolge. Beachten Sie, dass in den Protokollen immer ein Fehler für die letzten drei leeren Menüelemente auftritt, und nur manchmal den Fehler für die ersten drei erzeugt, auch wenn die Bildlaufebene nicht leer ist und den richtigen Text anzeigt (für die ersten drei wird manchmal gedruckt zu den Protokollen ohne Problem).
Ich habe APP_LOG
auf str_teasers
an verschiedenen Punkten versucht, und wenn es fehlschlägt, tut sie dies, nachdem ich menu_layer = menu_layer_create(bounds);
mein Menü erstellen rufen. Bevor ich diesen Aufruf tätige, kann ich alle Zeichenfolgen mit APP_LOG ohne Probleme ausgeben. Ich dachte, es wäre ein Heap-Fehler, aber ich habe Heap-Speicher (~ 8100 Bytes) vor und nach der Erstellung des Layers und meine App stürzt nicht ab.
Vielleicht vermisse ich etwas sehr einfach, aber ich kann meinen Fehler nicht finden. Ich habe den Speicher für str_teasers
richtig zugeordnet, glaube ich, also sehe ich nicht, warum es überhaupt geändert werden sollte. Ich habe einen modifizierten Beispielcode als Referenz eingefügt.
//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);
Sie scheinen keine 'Hauptfunktion 'zu haben. Ausführbare Anweisungen müssen innerhalb einer Funktion sein. Haben Sie 'stdlib.h' für' malloc' und 'string.h' für' strcpy' eingeschlossen? Haben Sie Ihren eigenen 'strtok' geliefert? In diesem Fall ist es nicht ratsam, den Namen einer Bibliotheksfunktion zu duplizieren. Siehe [MCVE] (http://stackoverflow.com/help/mcve). –
Dies ist nur ein Beispiel aus meiner 'main.c' Datei, es hat die erforderliche' main' Funktion. Die eigentliche Funktion ist viel größer, so dass dies nur die relevanten Teile sind. Und ja, ich musste mein eigenes 'strtok' liefern, weil Pebble den offiziellen Bibliotheksnamen nicht unterstützt, ich habe es von [hier] (http://www.opensource.apple.com/source/Libc/Libc-167/string) .subproj/strtok.c). Ich habe es überprüft und es scheint die richtigen Zeichenfolgen zurückzugeben, die mit einem Nullzeichen enden (jedenfalls würde 'strlen' null zurückgeben, glaube ich, wenn es nicht wäre). –
Sie müssen ausführbaren Code hinzufügen, der das Problem aufweist. Ein Klecks Code, den wir nicht ausführen können, ist schwer zu helfen. Außerdem, wenn Sie hier tonnenweise Code ausgeben, dann sieht es so aus, als hätten Sie nicht versucht, das Problem selbst einzugrenzen. – Harry