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

Pointer value from instance method being garbled. The cause seems to be dependent on buffer size

我正在尝试创建一个一维标签数组作为另一个二维数组中列中内容的参考。标签包含字母和数字。此外,我希望该方法具有通用性,以便尽可能适用于各种标签。

下面是代码和输出。

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] = 067_7
Main: kolname[5] = 077_7
Main: kolname[6] = 
Main: kolname[7] = Test1
Main: kolname[8] = Test2
Main: kolname[9] =  
Program ended with exit code: 0

所有 BUF 到 24 的输出都会很奇怪。如果我们将 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] = 7
Main: kolname[9] =  
Program ended with exit code: 0

我的问题如下:

  1. 为什么低于25的BUF输出不是我想要的?
  2. 为什么BUF = 25突然开始工作了,是不是和字符总数(label1+…+label4)等于24有关系?
  3. 为什么 BUF = 33 及以上时,输出又变得奇怪了?

……最后

  1. 如何将代码更改为适用于长度(大小)范围更广的标签的代码?

提前致谢!

你的缓冲区 label1label2label3label4test堆栈分配的 set_name。一旦 set_name returns 这些缓冲区的生命周期结束并且(堆栈)内存可用于 re-use。因此,您 set_name returns 观察到的任何结果本质上都是随机的。

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

如果您正在使用 Objective-C,您可能希望考虑使用 NSString,这将在 ARC 下自动 memory-managed。