2017-02-20 3 views
0

J'essaie de créer une matrice 1D d'étiquettes comme référence pour le contenu dans les colonnes d'un autre tableau 2D. Les étiquettes contiennent à la fois des lettres et des chiffres. De plus, j'aimerais que la méthode soit générique de telle sorte qu'elle fonctionne aussi bien que possible.La valeur du pointeur de la méthode d'instance est tronquée. La cause semble être dépendante de la taille de la mémoire tampon

Le code ci-dessous suit le code et la sortie.

main.m 

#define IKOL   10 
char *kolname [IKOL];  

for (int i = 0; i < IKOL; i++) { 
    *(kolname + i) = " "; 
} 

sub *skuld =[[sub alloc]init]; 
[skuld set_name: kolname]; 
for (int i = 0; i < IKOL; i++) { 
    printf("Main: kolname[%d] = %s\n", i, *(kolname + i)); 
} 

La méthode d'instance:

sub.m 
#define BUF   32 

- (void)set_name: (char *[IKOL]) name { 
    int number = 30; 
    char label1[BUF]; 
    char label2[BUF]; 
    char label3[BUF]; 
    char label4[BUF]; 
    char test[12] = "Test2"; 
    *(name + 0) = "Port1"; 
    *(name + 1) = "Seq4"; 
    *(name + 2) = "GH-12"; 
    *(name + 3) = "Port5"; 
    snprintf(label1, sizeof(label1), "DDB(%d)", number); 
    printf("Sub: label1 = %s\n", label1); 
    *(name + 4) = label1; 
    snprintf(label2, sizeof(label2), "σ(%d)", (number-16)); 
    printf("Sub: label2 = %s\n", label2); 
    *(name + 5) = label2; 
    snprintf(label3, sizeof(label3), "EMM(%d)", (number-7)); 
    printf("Sub: label3 = %s\n", label3); 
    *(name + 6) = label3; 
    *(name + 7) = "Test1"; 
    *(name + 8) = test; 
    printf("Sub: test = %s\n", test); 
} 

Si nous modifions BUF à 8, nous aurons la sortie suivante

Sub: label1 = DDB(30) 
Sub: label2 = σ(14) 
Sub: label3 = EMM(23) 
Sub: test = Test2 
Main: kolname[0] = Port1 
Main: kolname[1] = Seq4 
Main: kolname[2] = GH-12 
Main: kolname[3] = Port5 
Main: kolname[4] = \360\276\277_\377 
Main: kolname[5] = \360\277\277_\377 
Main: kolname[6] = 
Main: kolname[7] = Test1 
Main: kolname[8] = Test2 
Main: kolname[9] = 
Program ended with exit code: 0 

La sortie sera étrange pour tous BUF jusqu'à 24. Si nous avons mis BUF à 25 nous avons la sortie désirée:

Sub: label1 = DDB(30) 
Sub: label2 = σ(14) 
Sub: label3 = EMM(23) 
Sub: test = Test2 
Main: kolname[0] = Port1 
Main: kolname[1] = Seq4 
Main: kolname[2] = GH-12 
Main: kolname[3] = Port5 
Main: kolname[4] = DDB(30) 
Main: kolname[5] = σ(14) 
Main: kolname[6] = EMM(23) 
Main: kolname[7] = Test1 
Main: kolname[8] = Test2 
Main: kolname[9] = 
Program ended with exit code: 0 

Tout regardera même jusqu'à BUF = 33 où la principale différence est que le numéro 2 est manquant dans la fente 8.

Sub: label1 = DDB(30) 
Sub: label2 = σ(14) 
Sub: label3 = EMM(23) 
Sub: test = Test2 
Main: kolname[0] = Port1 
Main: kolname[1] = Seq4 
Main: kolname[2] = GH-12 
Main: kolname[3] = Port5 
Main: kolname[4] = DDB(30) 
Main: kolname[5] = σ(14) 
Main: kolname[6] = EMM(23) 
Main: kolname[7] = Test1 
Main: kolname[8] = Test 
Main: kolname[9] = 
Program ended with exit code: 0 

Si nous augmentons BUF plus, nous verrons même une sortie plus étrange. Voici un exemple pour BUF = 50.

Sub: label1 = DDB(30) 
Sub: label2 = σ(14) 
Sub: label3 = EMM(23) 
Sub: test = Test2 
Main: kolname[0] = Port1 
Main: kolname[1] = Seq4 
Main: kolname[2] = GH-12 
Main: kolname[3] = Port5 
Main: kolname[4] = DDB(30) 
Main: kolname[5] = σ(14) 
Main: kolname[6] = 
Main: kolname[7] = Test1 
Main: kolname[8] = \377 
Main: kolname[9] = 
Program ended with exit code: 0 

Mes questions sont les suivantes:

  1. Pourquoi ne pas la sortie que je veux devenir pour BUF moins de 25 ans? Pourquoi commence-t-il soudainement à fonctionner à BUF = 25. Cela a-t-il quelque chose à voir avec le fait que le nombre total de caractères (label1 + ... + label4) est égal à 24?
  2. Pourquoi la sortie devient-elle encore étrange pour BUF = 33 et plus?

... et enfin

  1. Comment puis-je changer le code à quelque chose qui fonctionne pour une variété d'étiquettes plus larges en termes de longueur (taille)?

Merci d'avance!

Répondre

2

Vos tampons label1, label2, label3, label4 et test sont pile alloué à l'intérieur deset_name. Une fois que set_name renvoie la durée de vie de ces tampons se termine et la mémoire (pile) est disponible pour la réutilisation. Tous les résultats que vous observez une fois les retours set_name sont donc essentiellement aléatoires.

Si vous souhaitez suivre la même conception, basée sur les chaînes C, vous devrez utiliser l'allocation dynamique/de tas des tampons dans set_name. Cela signifie également que vous serez responsable de la désaffectation ultérieure de ces tampons.

Si vous utilisez Objective-C, vous pouvez envisager d'utiliser NSString, qui sera automatiquement géré en mémoire sous ARC.

+0

Je ne comprends toujours pas pourquoi ma méthode semble fonctionner pour une petite fenêtre, 24 userjuicer

+0

L'apparence de travail est un résultat aléatoire. Lorsque les buffers alloués à la pile sont libérés, cela ne signifie pas que la mémoire utilisée est effacée. Lorsque vous utilisez plus tard, vos pointeurs maintenant invalides, ils se réfèrent toujours à la même mémoire physique et cette mémoire n'a pas été réutilisée et des fragments complètement écrasés de ce que vous avez stocké là peuvent être trouvés. – CRD

+0

Ahh, d'accord, je comprends. Merci! – userjuicer