我试图创建一个1D标签数组,作为另一个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到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时,一切看起来都是一样的,这里的主要区别是第2个在插槽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

如果我们增加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

我的问题如下:
为什么在25岁以下的BUF的输出没有达到我的要求?
为什么它突然在BUF=25时开始工作。是否与字符总数(label1+…+label4)等于24有关?
为什么BUF=33及以上的输出会再次变得奇怪?
…最后
如何将代码更改为在长度(大小)方面适用于更广泛的标签的代码?
提前谢谢你!

最佳答案

缓冲区label1label2label3label4testset_name内部进行堆栈分配。Onceset_name返回这些缓冲区结束的生存期,并且(堆栈)内存可供重用。因此,您观察到的任何一次set_name返回的结果基本上都是随机的。
如果您希望遵循基于C字符串的相同设计,则需要在set_name中使用缓冲区的动态/堆分配。这也意味着您将负责稍后释放这些缓冲区。
如果您使用的是Objective-C,您可能希望考虑使用NSString,它将在ARC下自动进行内存管理。

关于objective-c - 来自实例方法的指针值出现乱码。原因似乎取决于缓冲区大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42335436/

10-11 22:55
查看更多