动态字符串数组剂量工作

时间:2017-04-01 19:45:56

标签: c arrays dynamic-arrays calloc

我尝试使用calloc:

创建一个包含1000个字符长字符串的动态数组
int i;
char** strarr =(char**)calloc(argc,sizeof(char)*1000);
if(strarr == NULL)
    return 0;
strarr[0][0] ='a';
printf("%c\n",strarr[0][0]);

每当我尝试运行此代码时,我会在printf行上出现分段错误,我不知道为什么会发生这种情况(你可以假设argc大于0) 感谢

P.S。对不起,代码是文本格式,但即时通讯使用手机,所以我没有代码功能

2 个答案:

答案 0 :(得分:0)

试试这个:

mButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Calendar cal = Calendar.getInstance();
        int currentHour = cal.get(Calendar.HOUR_OF_DAY);
        int currentMinute = cal.get(Calendar.MINUTE);

        fixValues();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mTimePicker.setHour(currentHour);
            mTimePicker.setMinute(currentMinute);
        } else {
            mTimePicker.setCurrentHour(currentHour);
            mTimePicker.setCurrentMinute(currentMinute);
        }
    }
});

private void fixValues() {
    // bug is not reproducible in APIs 24 and above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) return;
    try {
        int hour, minute;
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
            hour = mTimePicker.getHour();
            minute = mTimePicker.getMinute();
        } else {
            hour = mTimePicker.getCurrentHour();
            minute = mTimePicker.getCurrentMinute();
        }

        Field mDelegateField = mTimePicker.getClass().getDeclaredField("mDelegate");
        mDelegateField.setAccessible(true);
        Class<?> clazz;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            clazz = Class.forName("android.widget.TimePickerClockDelegate");
        } else {
            clazz = Class.forName("android.widget.TimePickerSpinnerDelegate");
        }
        Field mInitialHourOfDayField = clazz.getDeclaredField("mInitialHourOfDay");
        Field mInitialMinuteField = clazz.getDeclaredField("mInitialMinute");
        mInitialHourOfDayField.setAccessible(true);
        mInitialMinuteField.setAccessible(true);
        mInitialHourOfDayField.setInt(mDelegateField.get(mTimePicker), hour);
        mInitialMinuteField.setInt(mDelegateField.get(mTimePicker), minute);
    } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

答案 1 :(得分:0)

您好,欢迎来到未定义行为的世界,这是C语言最黑暗的领域之一。你的代码有几个问题,在几种情况下会导致未定义的行为,但它们都会被执行,直到你到达printf行,你正在访问内存,你没有分配,这最终被你的系统和因此,产生了分段错误。

但我认为,最好自己完成代码。

  1. int i;行中声明的变量i不会在您发布的代码中的任何位置使用,但我想您以后需要它。
  2. 第一段代码是不正确的,在第二行中,您声明了一个字符串数组或char**。这意味着你有一个指向字符指针的指针。所以,你真正想做的是为那些指针分配内存,而不是为它们指向的字符分配内存。请注意,char消耗的内存量与char*不同。因此,这条线就是这条线。

    char** strarr = (char**) calloc(argc, sizeof(char*));
    

    这将为argc内存块分配内存,每个内存的大小为4或8字节,这取决于您的系统是32位还是64位。

  3. 您正在检查calloc函数是否返回NULL,这是一个非常好的做法。

  4. 接下来,您将需要为指针指向的字符串本身分配内存,您在上一行中为其分配了内存。这些行就可以了。

    for (int i = 0; i < argc; i++) {
        strarr[i] = (char*) calloc(1000, sizeof(char));
    }
    

    现在,我们将为argc大小的字符串数组的每个元素分配1000个字符的加长字符串。

  5. 之后,您可以按原样继续使用代码,我认为不会产生任何错误。请接受我的其他建议。学会爱valgrind。这是一个非常有用的程序,您可以使用它来运行代码,以便分析内存。这是我的第一步,每当我遇到分段错误时。