讀代碼時,寫測試代碼驗證自己的想法

讀代碼時,寫測試代碼驗證自己的想法
這兩天爲了編譯ruby0.49,可是費盡了心思。
後來,發現,爲了再現編譯中的錯誤,最好是自己寫測試代碼。
一。gdbm調試
因爲ruby049中有一個文件dbm.c,爲了編譯它,需要安裝gdbm。從來沒有用過dbm。於是在網上學安裝,並在網上找文件,再進行編譯,等本地小程序編譯後,再修改Makefile,dbm.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
 
//#include "/usr/include/gdbm/ndbm.h"
// On some systems you need to replace the above with
#include <gdbm-ndbm.h>
 
 
 
#include <string.h>
 
#define TEST_DB_FILE "/tmp/dbm1_test"
#define ITEMS_USED 3
 
/* A struct to use to test dbm */
struct test_data {
    char misc_chars[15];
    int  any_integer;
    char more_chars[21];
};
 
int main() {
 
    struct test_data items_to_store[ITEMS_USED];
    struct test_data item_retrieved;
 
    char key_to_use[20];
    int i, result;
 
    datum key_datum;
    datum data_datum;
    
    DBM *dbm_ptr;
 
    dbm_ptr = dbm_open(TEST_DB_FILE, O_RDWR | O_CREAT, 0666);
    if (!dbm_ptr) {
        fprintf(stderr, "Failed to open database\n");
        exit(EXIT_FAILURE);
    }
 
        /* put some data in the structures */
    memset(items_to_store, '\0', sizeof(items_to_store));
    strcpy(items_to_store[0].misc_chars, "First!");
    items_to_store[0].any_integer = 47;
    strcpy(items_to_store[0].more_chars, "foo");
    strcpy(items_to_store[1].misc_chars, "bar");
    items_to_store[1].any_integer = 13;
    strcpy(items_to_store[1].more_chars, "unlucky?");
    strcpy(items_to_store[2].misc_chars, "Third");
    items_to_store[2].any_integer = 3;
    strcpy(items_to_store[2].more_chars, "baz");
 
    for (i = 0; i < ITEMS_USED; i++) {
            /* build a key to use */
        sprintf(key_to_use, "%c%c%d",
            items_to_store[i].misc_chars[0],
            items_to_store[i].more_chars[0],
            items_to_store[i].any_integer);
 
            /* build the key datum strcture */
        key_datum.dptr = (void *)key_to_use;
        key_datum.dsize = strlen(key_to_use);
        data_datum.dptr = (void *)&items_to_store[i];
        data_datum.dsize = sizeof(struct test_data);
 
        result = dbm_store(dbm_ptr, key_datum, data_datum, DBM_REPLACE);
        if (result != 0) {
            fprintf(stderr, "dbm_store failed on key %s\n", key_to_use);
            exit(2);
        }
    } /* for */
 
        /* now try and retrieve some data */
    sprintf(key_to_use, "bu%d", 13); /* this is the key for the second item */
    key_datum.dptr = key_to_use;
    key_datum.dsize = strlen(key_to_use);
 
    data_datum = dbm_fetch(dbm_ptr, key_datum);
    if (data_datum.dptr) {
        printf("Data retrieved\n");
        memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize);
        printf("Retrieved item - %s %d %s\n",
               item_retrieved.misc_chars,
               item_retrieved.any_integer,
               item_retrieved.more_chars);
    }
    else {
        printf("No data found for key %s\n", key_to_use);
    }
 
    dbm_close(dbm_ptr);
 
    exit(EXIT_SUCCESS);
}
編譯命令如下
gcc t1.c -lgdbm -lgdbm_compat
yang@DESKTOP-V9HS3B6:~/ruby049$
爲了搞這個gdbm,我至少折騰了兩天。甚至想去讀gdbm的源碼。
二。指針相關錯誤
我開始以爲是指針類型相關錯誤,如
#include<stdio.h>
#include<stdlib.h>

int main()
{
    struct fu {
        int num;
    };
    struct zi {
        struct  fu obj_fu;
        int key;
    };
    struct  zi obj_zi;
    struct  fu *q=(struct fu *) malloc(sizeof(struct zi));
    printf("ok\n");
    return 0;
}
以爲,父類型的指針比子類型的大。於是寫測試程序。結果可以通過。所以問題,不在這兒。
在網上找資料後,發現
#include<stdio.h>
void test()
{
    int n=10;
    (void *)n;

}
int main()
{
    test();
return 0;
}
這樣,居然就重現了錯誤。因爲64位的指針值的24位整數,而32位的好像是16位。於是就再轉一下。
#include<stdio.h>
void test()
{
    int n=10;
    (void *)(long)n;

}
int main()
{
    test();
return 0;
}
gcc t2.c
yang@DESKTOP-V9HS3B6:~/ruby049$ ./a.out
ok
從昨天開始,我爲了去年1萬多條警告,就不停的加(long)
#include<stdio.h>
int main()
{
    int a=10;
    printf("%p",&a);
    return 0;
}
這是爲了打印地址的值。
gcc t4.c
yang@DESKTOP-V9HS3B6:~/ruby049$ ./a.out
0x7fffc4a4b89cyang@DESKTOP-V9HS3B6:~/ruby049$
但費盡這麼多,執行程序時,還是報錯誤。只能打印出版本號。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章