在eclipse

时间:2016-03-26 14:59:49

标签: c eclipse pointers eclipse-cdt

我很长时间没有触及过C.我的第一语言是C.但后来我们学习了C ++,Java和C#(在大学期间)。现在我的工作主要涉及Java和groovy。突然间我又要做C了。我不熟悉行业如何使用C,因为我从来没有在项目中使用C语言。

我开始使用eclipse CDT,在Windows 10上使用MinGW。我的新程序迅速发展壮大。我缺乏经验。当我运行时,我的程序曾经崩溃,显示Windows对话框“MyProgram.exe已停止工作”。现在我不知道什么是错的。编译很干净,没有错误,但只有一个警告。现在从Java世界开始,我就像警告一样并不致命。所以我只是忽略它(我认为我缺乏C经验)。并继续调试找到了原因。意识到警告确实是关于原因的。因调试浪费时间而感到精神沮丧。

所以这是我原始代码中的代码复制问题:

1    #include "stdio.h"
2    #include "limits.h"
3    
4    typedef struct TempStruct TempStruct;
5    
6    struct TempStruct
7    {
8        int a;
9        TempStruct *next;
10    };
11    
12    int function1(TempStruct *param)
13    {
14        return param == NULL;
15    }
16    
17    int function2(TempStruct **param)
18    {
19        if(function1(param))
20        {
21            return INT_MIN;
22        }
23        *param = (*param)->next;
24        return 0;
25    }
26    
27    int main()
28    {
29        TempStruct *tempStructObj = NULL;
30        function2(&tempStructObj);
31        printf("Does not reach here!!!");
32        return 0;
33    }

我的C-noob眼睛没有看到任何错误。很好,我知道如何进行调试。我在调试中得到了以下信息:

enter image description here

main()中完成此操作:*tempStructObj = NULL。所以,我希望function1()返回1,使function2()从第21行返回。 问题是function1()需要TempStruct*。但在第19行,我通过了它**param。所以在function1()内,param不是NULL。所以它返回false(我猜是0)。所以function2()没有从第21行返回。它执行了(*param)->next,因此程序崩溃了。

我的问题:

  • Q1。不应该将此问题报告为错误而不是警告?是否有任何设置可以向错误报告此类可能致命的警告?
  • Q2。 eclipse会在某处记录这种突然的应用程序崩溃的原因吗?因此,我可以简单地参考可能指定导致崩溃的行号的报告,而不是通过逐行调试来进行调试
  • Q3。处理此类错误的行业标准方法是什么?当然有人会说不要犯这个错误。但我问的是为避免这些错误或自动检测它们而采取的预防措施。就像上面一样,我问了一些设置,让eclipse报告这个问题是致命的,或者让崩溃产生报告,这样就可以快速修复东西而不是长时间的调试。您是否使用(eclipse CDT + MinGW + Windows)更好的(并且可能涉及更小的学习曲线)替代方案,它将提供更强大的调试,以便我可以避免此类错误。
  • Q4。在上图的第1点中,Error: Multiple errors reported...是什么。偶尔会发生这种情况,但并非总是如此,在5次调试会话中说一次。这种临时行为背后的原因是什么?
  • Q5。在上图中的第3点,0x62ff2cparam的{​​{1}}值是多少?如果我将function1()的签名正确保留为function1()并将内部引用正确更改为int function1(TempStruct **param),则*param正确*param(即0x0): enter image description here

    修改

      Ideone的
    1. This适用(使用C)&打印“不到达!!!”。所以不知道它是如何处理的NULL
    2. 关于ideone的
    3. This(使用C99 Strict)确实会出错(不是警告)。

2 个答案:

答案 0 :(得分:3)

Q1。不,他们是警告,因为他们是合法的C代码。 可能可能你想要这样的代码。您可以在gcc上使用-Werror来发出错误警告。还要添加一些其他标志以打开更多警告,例如-Wall -Wpedantic -Wextra -Wshadow -Wconversion -Wno-sign-compare等。这将更接近您在使用Java时可能习惯的内容; - )

Q2。至少在Linux上你有coredumps,iirc Windows是minidumps。这些可以与相应的可执行文件一起加载到调试器中。然后你可以访问回溯,值等。

Q3。

  

像上面一样,我问过设置让eclipse报告这个问题是致命的,或者让崩溃产生报告,这样可以快速修复东西,而不是长时间的调试。

记录自己。也可以使用宏来缓解这种情况。

  

你是否使用更好的(并且可能涉及更小的学习曲线)替代(eclipse CDT + MinGW + Windows),这将提供更强大的调试,以便我可以避免这样的错误。

IDE与C imho无关。使用Linux与本机GCC相反,MinGW很不错但它可能令人生畏(我的经验)。 当然MS VSC ++也可以编译C,但它只适用于C ++兼容,因此并不特定于一个标准。

Q4。好吧,列出了多个错误。如果它很难重现它可能是你的设置中的一个问题,这正是我在Windows上使用MinGW的经验。

Q5。它是地址 - 你有一个指向指针的指针,所以第一个(“外部”)指针就是那个地址,指向另一个指针NULL。 或者更详细地说: tempStructObj是指向NULL的指针(即int_ptr,其中包含值0x0

function2int_ptr传递保存自动变量int_ptr tempStructObj的半随机值/地址的另一个&tempStructObj IE浏览器。你有这样的:

地址tempStructObjfunction1

在RAM中

。 然后在调用NULL时,传递this(不是 - *param)指针的值。当然,比较总是错误的。 你需要比较一下 NULLgcc -std=c99 -Wall -Wpedantic -Wextra -Wshadow -Wconversion -Wno-sign-compare -o main main.c main.c: In function ‘function2’: main.c:19:18: warning: passing argument 1 of ‘function1’ from incompatible pointer type [-Wincompatible-pointer-types] if(function1(param)) ^ main.c:12:5: note: expected ‘TempStruct * {aka struct TempStruct *}’ but argument is of type ‘TempStruct ** {aka struct TempStruct **}’ int function1(TempStruct *param) ^

更多: 如果您使用GCC进行编译(在Linux上)并使用非常详细的标志,您将获得:

function1

确切地说你遇到的问题是^^

此外,我完全删除了struct,这完全没必要,只是模糊了代码。另外,我会为typedef_t使用不同的名称,后者附加\n。我还将它移到一段较短的代码中。 在旁注中:在printf() - 呼叫中添加#include <stdio.h> #include <limits.h> typedef struct TempStruct_s { int a; struct TempStruct_s *next; } TempStruct_t; int function(TempStruct_t **param) { if(!*param) { return INT_MIN; } *param = (*param)->next; return 0; } int main() { TempStruct_t *tempStructObj = NULL; function(&tempStructObj); printf("Does not reach here!!!\n"); return 0; }

编辑代码:

<html>
<body>
<script>
    $(document).ready(function() {
        $.ajax({
            url: "Search.html",
            type: "POST",
            dataType : "json",

            success: function (result) {
                console.log(result);
                if(result.status == 200 && result.validationFailed ){
                    alert(result.message);
                }
            },

            error: function(result){
                console.log(result);
                if(error.responseText == 'showAlert'){
                    alert( "Sorry, there was a problem!" );
                }
            }
            })
            });
    }   
    </script>
    <form action="/process_post" method="POST">
        <select name="SearchTypes">
            <option value="Author" selected>Author</option>
            <option value="Mention">Mention</option>
            <option value="Tag">Tag</option>
        </select>
        <input type="text" name="term">
        <br><br>
        <input type="submit" value="Submit">
    </form>

</body>
</html>

答案 1 :(得分:0)

当你

TempStruct *tempStructObj = NULL;
function2(&tempStructObj);

您要将变量function2(0x62ff2c)的地址发送到tempStructObj。做的时候

if(function1(param)){
    return INT_MIN;
}

您正在发送相同的地址(0x62ff2c)。因此,param == NULLfalse

问题5:如果你按照建议使用正确的签名,那么你检查tempStructObj指向的值,这是你想要的,一切正常。

您无法访问内存0x4的错误是由于您的结构和错误的空检查。 (*param)->next预计会在具有int和另一个指针的内存区域上工作。但是,*param指向地址0x0,因此int位于地址0x0,next指针位于地址0x4,因此出错。