实例方法的指针值是乱码。原因似乎取决于缓冲区大小

时间:2017-02-20 02:13:28

标签: objective-c c pointers printf buffer

我正在尝试创建一个标签的一维数组,作为另一个2D数组中列内容的参考。标签包含字母和数字。此外,我希望这种方法能够通用,使其尽可能多种标签。

下面是代码和输出。

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));
}

实例方法:

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);
}

如果我们将BUF改为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] = \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

对于所有BUF,输出将是奇怪的。如果我们将BUF设置为25,我们有所需的输出:

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 

一切看起来都一样,直到BUF = 33,其中主要区别在于插槽8中缺少数字2。

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 

如果我们更多地增加BUF,我们会看到更奇怪的输出。 以下是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

我的问题如下:

  1. 为什么输出变得不像我想要的25岁以下的BUF?
  2. 为什么它突然开始在BUF = 25开始工作。是否与字符总数(label1 + ... + label4)等于24有关?
  3. 为什么BUF = 33及以上输出再次变得奇怪?
  4. ......最后

    1. 如何根据长度(尺寸)将代码更改为适用于各种标签的内容?
    2. 提前谢谢!

1 个答案:

答案 0 :(得分:2)

您的缓冲区label1label2label3label4testset_name堆叠 。一旦set_name返回这些缓冲区的生命周期结束,并且(堆栈)内存可用于重用。因此,set_name返回后您观察到的任何结果都是随机的。

如果您希望遵循相同的设计,基于C字符串,您将需要在set_name中使用缓冲区的动态/堆分配。这也意味着您将负责稍后释放这些缓冲区。

如果您使用的是Objective-C,您可以考虑使用NSString,它将在ARC下自动进行内存管理。