【问题标题】:sprintf for loop segfaultsprintf for 循环段错误
【发布时间】:2011-07-11 22:07:00
【问题描述】:

您好,我需要帮助理解 sprintf 和 C 字符数组。我来自 Java 背景,理解 C 到指针(我一直在自学 C :/)。

无论如何,我在使用 sprintf 时遇到了段错误,需要回答几个问题。 1) sprintf 是否覆盖字符数组中的其他元素?如果是这样,不应该将第一个元素设置为 0 修复它吗?

2) char 数组没有足够的空间来放置元素是否属于段错误?

char buffer[15];
char dbuff[15];
char* numer;//these variables don't cause the problem, 
// but just thought I'd include them
char* denom;
char** num_ptr = &numer;
char** denom_ptr = &denom;
for(j=1; j < nR; j++)
{
    for(i=1;i < nC; i++)
    {
        sprintf(buffer,"%i",sorts[j][i]);  //problems after 1 loop
        printf("buffer %s",buffer); 
        sprintf(dbuff,"%f",srcMat[j][i]);
        // a new incoming rank
        if(g_hash_table_lookup(rankCnt,buffer) == NULL)
        {
            avgholder[k++] = sorts[j][i];

            printf("%i kkkk      %i sorts\n",k,sorts[j][i]);

            g_hash_table_insert(rankAvg,buffer,dbuff); //problem occurs here
            g_hash_table_insert(rankCnt,buffer, (void*)1);
        }
    }

我尝试过:添加缓冲区/dbuff[0]=0、memset 和其他几种方法,但我忘记了 :(。我想我需要分配内存,但我从来没有这样做过,这样行吗? 另外我基本上在做的是读取一个二维矩阵的文件,我将它分类,并使用 glib 的 hashmap 来映射它们以进行矩阵操作。任何帮助都会很棒!

程序收到信号SIGSEGV,分段错误。 0x0023af03 在?? () 来自 /lib/i386-linux-gnu/libc.so.6

(gdb) 回溯

0x0023af03 在?? () 来自 /lib/i386-linux-gnu/libc.so.6

0x00238850 in strtod() from /lib/i386-linux-gnu/libc.so.6

0x00000000 在 ?? ()

*EDIT 抱歉,但我认为数组初始化不是问题。对于 srcMat,它的 double srcMat[nR][nC] 其中 nR 和 nC 是整数,即行和列。

对于我使用 int sorts[nR][nC] 的排序;然后我根据矩阵列的排名用整数值填充它。

GHashTable* rankAvg= g_hash_table_new(g_str_hash, g_str_equal);
GHashTable* rankCnt = g_hash_table_new(g_str_hash, g_str_equal);

感谢大家的帮助。

另外,我从 1 开始而不是 0 的原因是输入矩阵文件包含标题行和标题列,这两个东西不需要我的矩阵分位数归一化。

也有点偏离主题,但一个普遍的问题,我无法将 gpointers 转换回双精度数(我可以转换成整数),所以现在我只是将元素存储为字符串,当我存储 atof(double) 时需要他们。对此有什么想法吗?

编辑 #2 对不起,伙计们,但我只是缩小了问题的范围,实际上问题出在 ghashtable 插入方法上,我完成了 1 次循环迭代,第二次插入导致段错误。

【问题讨论】:

  • 这个sorts[][] 数组是如何声明的? srcMat[][] 也一样
  • 您还没有显示sorts 的定义。而且您还没有向我们展示您是如何初始化buffer 的。 (请注意,在 C 中,原始类型不会自动初始化为零,除非它们是全局或静态的)。
  • @Oli buffer 初始化并不重要,因为他是 sprintf 的。
  • @hexa:啊,是的,我没有发现这是第一个sprintf的参数!

标签: c arrays segmentation-fault printf


【解决方案1】:

数组中的空间不足肯定可能造成段错误——取决于数组在内存中的位置。但请注意您的数组边界是什么:您从 1 变为 nR-1nC-1。 C 有基于 0 的数组。你确定你在那里做你想做的事吗?

【讨论】:

  • 是的,但现在我认为这不是问题所在,尤其是当二维数组超过 10 并且我只完成 1 次循环迭代时。我也犯了一个错误,我做了更多的printf函数并将问题重新定位到hashtables插入方法
【解决方案2】:

在 C 中,数组索引从 0 开始,而不是从 1。尝试在 for 循环中将 ij 初始化为 0,您可能访问了错误的内存,因此出现了 seg 错误。 s>

编辑好吧,如果你故意用 1 初始化它,你应该循环到 nR-1nC-1,这样你就不会访问错误的内存。

EDIT2

这行看起来很可疑:

g_hash_table_insert(rankCnt,buffer, (void*)1);

尝试在某处声明一个 int,将其值设为 1 并将其作为参数传递。如果它是你应该传递的 int ......这个函数的调用签名如何?

int myint = 1;
g_hash_table_insert(rankCnt,buffer, &myint);

【讨论】:

  • 不可能,因为我直接从具有标题行和标题列的文本文件中翻录。我不需要那些用于矩阵计算,所以我从 1 开始(或者在我的情况下,我在初始化源矩阵时将它们设置为 0)。这是我的错误程序收到信号 SIGSEGV,分段错误。 0x0023af03 在?? () 来自 /lib/i386-linux-gnu/libc.so.6 (gdb) 回溯 #0 0x0023af03 in ?? () from /lib/i386-linux-gnu/libc.so.6 #1 0x00238850 in strtod () from /lib/i386-linux-gnu/libc.so.6 #2 0x00000000 in ?? ()
  • 顺便说一句,你需要用调试符号编译你的程序,这样 gdb 才能打印出更好的跟踪。将-ggdb 添加到您的编译中,看看您在 gdb 中得到了什么。
  • o 好的,谢谢你的提示,仍然习惯了 C。另外,我稍微编辑了我的第一篇文章,在错误所在的位置上犯了一个错误,实际上完全改变了 :( 虽然我仍然认为 theres sprintf 发生了什么
【解决方案3】:

恐怕库中有一些错误...我在某些特定的 Gtk+ 程序中也遇到了一些奇怪的分段错误——我不知道有什么意义,因为我未能在测试中返回错误.但是,在我的情况下,分段错误发生在我 malloc 24*64 字节的内存大小之后,其中 24 是结构的大小,这不是重点——重点是只有在 64 时才会出现错误——它适用于所有其他值 - 没有理由 64 可能是唯一的例外!

当 gdb 将错误追溯到 /lib/i386-linux-gnu/libc.so.6 时,与您的问题的来源相同——尽管它们可能有不同的原因——这就是我找到你的原因问题在这里——我真的不认为这是因为我的代码或你的代码。

【讨论】:

    猜你喜欢
    • 2016-07-27
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 2011-11-03
    相关资源
    最近更新 更多