2013-10-13 59 views
0

我正在嘗試使用計算給定數字的斐波納契的示例項目來學習CMake。我的項目最初包含一個「.c」文件和標題。我能夠用CMake構建並運行而沒有問題。現在我試圖學習如何通過將我的fibnoacci函數移動到單獨的「.c」文件來鏈接庫,我使用CMake編譯成可鏈接的庫。它的構建沒有問題,但運行時會引發分段錯誤。我的項目結構是:CMake Noob分段錯誤問題

fib 
| 
*---MathFunctions 
| | 
| *----CMakeLists.txt 
| | 
| *----myfib.h 
| 
*---CMakeLists.txt 
| 
*---fib.c 
| 
*---fib.h 
| 
*---myfib.c 
| 
*---Config.in.h 

MathFunctions文件夾下的CMakeLists.txt爲空。所有的程序邏輯都在fib.c和myfib.c中。所有構建的是在頂部的CMakeLists.txt

fib.c:

# include "stdio.h" 
# include "stdlib.h" 
# include "Config.h" 
#include "myfib.h" 

void internalfib(int num) 
{ 
    printf("Internally defined fib\n"); 
    int a, b; 
    a = 0; 
    b = 1; 
    printf("custom fib of %d", b); 
    for(int i = 0; i + a <= num; b = i) { 
     i = a + b; 
     a = b; 
     printf(", %d", i); 
    } 
} 

int main(int argc, char** argv) { 
    fprintf(stdout,"%s Version %d.%d\n", 
       argv[0], 
       VERSION_MAJOR, 
       VERSION_MINOR); 
#ifdef SHOW_OWNER 
    fprintf(stdout, "Project Owner: %s\n", OWNER); 
#endif 
    myfib(atof(argv[1])); 
    printf("\n"); 
    return EXIT_SUCCESS; 
} 

myfib.c:

# include "stdio.h" 
# include "stdlib.h" 

void myfib(int num) 
{ 
    printf("custom myfib"); 
    int a, b; 
    a = 0; 
    b = 1; 
    printf("custom fib of %d", b); 
    for(int i = 0; i + a <= num; b = i) { 
     i = a + b; 
     a = b; 
     printf(", %d", i); 
    } 
} 

的CMakeLists.txt:

#Specify the version being used aswell as the language 
cmake_minimum_required(VERSION 2.6) 
#Name your project here 
project(fibonacci) 
enable_testing() 
set (VERSION_MAJOR 1) 
set (VERSION_MINOR 0) 

configure_file (
    "${PROJECT_SOURCE_DIR}/Config.h.in" 
    "${PROJECT_BINARY_DIR}/Config.h" 
) 

option (SHOW_OWNER "Show the name of the project owner" ON) 

#Sends the -std=c99 flag to the gcc compiler 
add_definitions(-std=c99) 

include_directories("${PROJECT_BINARY_DIR}") 
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") 
add_subdirectory (MathFunctions) 
add_library(MathFunctions myfib.c) 

#This tells CMake to fib.c and name it fibonacci 
add_executable(fibonacci fib.c) 
target_link_libraries (fibonacci MathFunctions) 

#test that fibonacci runs 
add_test (FibonacciRuns fibonacci 5) 
#Test the fibonacci of 5 
add_test (FibonacciCompare5 fibonacci 5) 

set_tests_properties (FibonacciCompare5 PROPERTIES PASS_REGULAR_EXPRESSION "1, 1, 2, 3, 5") 

install (TARGETS fibonacci DESTINATION ${PROJECT_BINARY_DIR}/bin) 

運行後我運行的build文件夾中的「..cmake」和「make」:

~/dev/cworkshop/fib/build$ ./fibonacci 
./fibonacci Version 1.0 
Project Owner: Clifton C. Craig 
Segmentation fault: 11 

我哪裏錯了?

+1

狂猜:'myfib.h'不包含'myfib'的有效原型,你沒有注意編譯器警告(或者沒有啓用它們),並且你正在使用'atof'其使用不受保證(提示:'f'代表'浮動',斐波那契數字是整數)。 –

+0

如果您要發佈代碼,請發佈一個*最小的工作示例*,而不是一半的代碼與大量的註釋掉並因此不必要的代碼。很煩人地滾動你明顯沒有使用的代碼(註釋掉),但是顯然這些代碼足以增加問題的重要性。你還沒有發佈頭文件。你有沒有使用調試器來確定段錯誤的位置? – simont

+0

謝謝!我沒有意識到(直到你指出atof()的東西),我正在省略我自己的程序的參數!當參數不存在時,我當然會遇到一個錯誤...它會嘗試訪問它並不擁有的內存!感謝名單!我會編輯我的問題更明顯一些。 – Cliff

回答

3

您是否確實確定由於您的構建系統,您正在收到段錯誤?

您的代碼需要輸入,而您確實不檢查輸入是否爲。從fib.c:26

myfib(atof(argv[1])); 

如果沒有給出參數,你的代碼會試圖讀取你沒有提供(和段錯誤)的數據。如果你運行你的代碼:./fibonacci 3,你會打印myfib。我會猜測這是你的問題。


其他的事情要考慮:

  • 給人代碼的一部分時,儘量保證它要麼最小的,完整的,或者準確地描述你的問題。大塊註釋掉的代碼與問題無關,在這種情況下,不提供頭文件和Config.h.in(它們是獲得示例編譯所需的)。
  • myfib.cmyfib.h位於不同的文件夾中。如果myfib.cMathFunctions庫的一部分,我會將源代碼放入該子目錄中。 this one,其中有一個CMakeLists.txt文件,其中包含行:

    add_library(MathFunctions mysqrt.cxx)

    MathFunctions庫這是在教程中,我認爲你在下面解釋。

  • 正如@n所指出的那樣。m在評論中,atoffloat作爲輸入 - 斐波那契數列使用int(因此atoi更合適)生成。

  • 對於您的示例,我不會使用add_definitions來設置編譯器標誌。更好的方法(項目範圍)是使用set (CMAKE_CXX_FLAGS "-O0 -g -Wall")。 (有很多useful CMake Variables)。雖然add_definitions的作品,它不是你正在做的工作的最佳工具。 :)

+0

我在刷新和看到這個答案之前回復了之前的評論者。你是絕對正確的!我忘記了引發段錯誤的參數!感謝你們倆! – Cliff