一个问题问我这段代码是否包含任何错误。 编译器没有给我任何错误,但这段代码包含一些我不知道的参数
代码是这样的:
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;
}
可能的解决方案是:
答案 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
)变量p
和q
的指针。 p
是
使用malloc
和q
返回的值初始化的内容未初始化。
它和做的一样:
int *p;
int *q;
p = malloc(n*sizeof(int));
但是在一行中。
下一部分是有趣的:
for (q=p; q<p+n; ++q)
*q = 0;
首先,我纠正了这一情况并将其分为两行。
您可以按如下方式阅读此循环:
q
相同的值初始化p
,即p
和q
指向开头
已分配的内存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)