这段代码中有错误吗?

时间:2018-01-27 16:15:25

标签: c

一个问题问我这段代码是否包含任何错误。 编译器没有给我任何错误,但这段代码包含一些我不知道的参数

代码是这样的:

int* mycalloc(int n) {
   int *p = malloc(n*sizeof(int)), *q; //what does the ", *q"?
   for (q=p; q<=p+n; ++q) *q = 0; 
   return p;
}

可能的解决方案是:

  1. 程序正确
  2. 第1行有错误
  3. 第2行有错误
  4. 第3行有错误
  5. 第4行有错误

3 个答案:

答案 0 :(得分:2)

上述代码中没有compile time错误,但在运行时,由于q<=p+n,它会崩溃。 q只是一个整数指针。 它应该是

for (q=p; q<p+n; ++q) /** it works even though n is zero or you can add seperate if condition for the same, this may be the interviewer concern **/
    *q = 0;

答案 1 :(得分:0)

mymalloc正在做的是为n整数分配空间并进行初始化 他们用0。

这可以这样做:

int *mymalloc(size_t n)
{
    int *arr = malloc(n * sizeof *arr);
    if(arr == NULL)
        return NULL;

    memset(arr, 0, n * sizeof *arr);
    return arr;
}

或更好

int *mymalloc(size_t n)
{
    return calloc(n, sizeof int);
}

你的函数执行此操作的方式是使用a循环遍历数组 指针q。让我解释一下

int *p = malloc(n*sizeof(int)), *q;

它声明了两个int*(指向int)变量pq的指针。 p是 使用mallocq返回的值初始化的内容未初始化。 它和做的一样:

int *p;
int *q;

p = malloc(n*sizeof(int));

但是在一行中。

下一部分是有趣的:

for (q=p; q<p+n; ++q)
    *q = 0; 

首先,我纠正了这一情况并将其分为两行。

您可以按如下方式阅读此循环:

  • 使用与q相同的值初始化p,即pq指向开头 已分配的内存
  • q指向超出分配的内存
  • 时结束循环
  • 在循环结束时,执行++q,这会使q转到下一个int
  • 在循环中执行*q = 0,相当于q[0] = 0,从而将整数设置为 q指向的0。

让我们考虑一下内存布局。让我们说n = 5。在我的图片? 代表一个未知的价值。

BEFORE THE LOOP
b = the start of the allocated memory aka malloc return value
si = size of an integer in bytes, mostly 4

                                                       (beyond the limits)
     b+0      b+1*si     b+2*si   b+3*si     b+4*si    b+5*si
     +---------+---------+---------+---------+---------+
     | ????    | ????    | ????    | ????    | ????    |
     +---------+---------+---------+---------+---------+
     ^
     |
     p

在第一个循环中,q设置为p并执行*q = 0。它和...一样 做p[0] = 0

FIRST ITERATION
b = the start of the allocated memory aka malloc return value
si = size of an integer in bytes, mostly 4

                                                       (beyond the limits)
     b+0      b+1*si     b+2*si   b+3*si     b+4*si    b+5*si
     +---------+---------+---------+---------+---------+
     | 0       | ????    | ????    | ????    | ????    |
     +---------+---------+---------+---------+---------+
     ^
     |
     p,q

这就是*q=0之后内存的样子。然后下一个循环是 已执行,但在执行q++之前

BEFORE SECOND ITERATION, `q++`
b = the start of the allocated memory aka malloc return value
si = size of an integer in bytes, mostly 4

                                                       (beyond the limits)
     b+0      b+1*si     b+2*si   b+3*si     b+4*si    b+5*si
     +---------+---------+---------+---------+---------+
     | 0       | ????    | ????    | ????    | ????    |
     +---------+---------+---------+---------+---------+
     ^         ^
     |         |
     p         q

现在执行*q = 0,这与p[1] = 0

相同
SECOND ITERATION,
b = the start of the allocated memory aka malloc return value
si = size of an integer in bytes, mostly 4

                                                       (beyond the limits)
     b+0      b+1*si     b+2*si   b+3*si     b+4*si    b+5*si
     +---------+---------+---------+---------+---------+
     | 0       | 0       | ????    | ????    | ????    |
     +---------+---------+---------+---------+---------+
     ^         ^
     |         |
     p         q

然后循环继续,你现在得到了重点。这就是你的代码中的原因 循环q <= p+n的条件是错误的,因为它会更进一步 比它需要的还要写一个超出极限的0。

你循环使用指针算法。指针算法类似于常规 算术(即加法,用自然数减法),需要 考虑对象的大小。

考虑这段代码

int p[] = { 1, 2, 3, 4, 5};
int *q = p;

p是维度为int的数组5. int的常见大小为4, 表示数组q需要20个字节的内存。前4个字节用于 p[0]p[1]的下一个4,等等q是指向int的指针 数组p的第一个元素。实际上这段代码相当于

int p[] = { 1, 2, 3, 4, 5};
int *q = &(p[0]);

这就是人们所谓的数组衰减,这意味着你可以像访问数组那样访问数组 如果指针在哪里。对于指针算术,几乎没有区别 两者之间。

什么是指针算术?

这:p+2。这将为您提供p之后2个空格的指针。注意 我使用单词space而不是byte,这是因为取决于类型 p的字节数将不同。数学上是什么编译器 正在做的是从

计算地址
  

地址,其中p指向+ 2x(int的字节数)

     

因为编译器知道指针的类型。

这就是为什么当p++是指针时,您还可以使用p这样的表达式。它是 正在做p = p + 1 p = &(p[1]);

b is the base address where the memory starts

memory
address      b+0      b+1*si     b+2*si   b+3*si     b+4*si    
             +---------+---------+---------+---------+---------+
             | 1       | 2       | 3       | 4       | 5       |
             +---------+---------+---------+---------+---------+
             p         p+1       p+2       p+3       p+4

pointer
(pointer arithmetic)

答案 2 :(得分:0)

import cv2
import numpy as np
import scipy.ndimage
from sklearn.externals import joblib
from tools import *
#from ml import *
import argparse
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import confusion_matrix
from sklearn.externals import joblib
from sklearn import svm
import numpy as np
import os
import cv2



parser = argparse.ArgumentParser()
parser.add_argument('--mode', '-mode', help="Mode : train or predict", type=str)
parser.add_argument('--a', '-algorithm', help="algorithm/model name", type=str)
parser.add_argument('--i', '-image', help="licence plate to read", type=str)
parser.add_argument('--model', '-model', help="Model file path", type=str)
#parser.add_argument('--d', '-dataset', help="dataset folder path", type=str)